I'm trying to do a query through NHibernate where the criterion for the result depends on a referenced table's ID. How do I do this? Let's look at a simple example:
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
public Bar ReferencedBar { get; set; }
}
public class Bar
{
public int Id { get; set; }
public string Name { get; set; }
}
Foo is then mapped to Bar:
public class FooMapping : ClassMap<Foo>
{
public FooMapping()
{
Id(c => c.Id).GeneratedBy.HiLo("1");
Map(c => c.Name).Not.Nullable().Length(100);
References(c => c.Bar);
}
}
Now I want to get all Foo's from the Database which reference a specific Bar by id. This function is using Criteria, but please 开发者_C百科give examples using something else if you feel it's better:
public IList<Foo> GetAllFoosReferencingBar(int barId)
{
using (var tx = Session.BeginTransaction())
{
var result = Session.CreateCriteria(typeof(Foo))
.Add(Restrictions./* foo.ReferencedBar == id */) // <-- How to add restriction using id?
.List<Foo>();
tx.Commit();
return result;
}
}
When I try to do this with, I get the exception:
.Add( Restrictions.Eq( "ReferencedBar", 32 ) );
Type mismatch in NHibernate.Criterion.SimpleExpression: ReferencedBar expected type Bar, actual type System.Int32
I do not have a reference object to Bar with id 32 yet and do not want to create one...
If Bar is lazy-loadedable (it is by default) then you can "Load" a proxy of Bar with its Id. You can pass that proxy instance as your reference to Bar in the criteria:
var result = Session.CreateCriteria(typeof(Foo))
.Add(Expression.Eq("ReferenceBar", Session.Load<Bar>(barId)))
.List<Foo>();
This results in the SQL query you expect without having to join to Bar.
CreateAlias
should help you out, like so:
var result = Session.CreateCriteria(typeof(Foo))
.CreateAlias("ReferencedBar", "bar")
.Add(Expression.Eq("bar.Id", barId))
.List<Foo>();
精彩评论