I'm trying to limit the result set of a mapped collection.
Here is a simple model:
public class Table1 {
public virtual long Id { get; set; }
public virtual IList<Table2> Table2s { get; set; }
}
public class Table2 {
public virtual long Id { get; set; }
public virtual long Table1Id { get; set; }
public virtual Table1 Table1 { get; set; }
public virtual string Field { get; set; }
}
public class Table1Map : ClassMap<Table1> {
public Table1Map () {
Table("Table1");
Id(x => x.Id).Column("Id").Not.Nullable().CustomType("Int64").GeneratedBy.Native();
HasMany<Table2>(x => x.Table2s).Inverse().Not.LazyLoad().KeyColumns.Add("Table1Id").Fetch.Join();
}
}
public class Table2Map : ClassMap<Table2> {
public Table2Map () {
Table("Table2");
Id(x => x.Id).Column("Id").Not.Nullable().CustomType("Int64").GeneratedBy.Native();
Map(x => x.Table1Id).Column("Table1Id").Not.Nullable().CustomType("Int64");
Map(x => x.Field).Column("Field").Not.Nullable().CustomType("AnsiString").Length(25);
References<Table1>(x => x.Table1, "Table1Id").Cascade.None();
}
}
I want to select all Table1
s. I also want to select all Table2
s that meet a certain criteria (Table2.Field = 'value'
), but I don't want to limit my Table1
s, so select null Table2
s if they don't meet the criteria. If I want to do this in SQL I'd do the following:
SELECT *
FROM
Table1
LEFT OUTER JOIN Table2 ON Table1.Id = Table2.Table1Id
WHERE
Table2.Field = 'value' or Table2.Field IS NULL
How should I structure my NHibernate query to achieve the desired result? I'd like a list of Table1
s, and within each Table1
I'd like either an empty list of Table2
s (because no Table2
s met the criteria), or a list of Table2
s that met the creteria.
I'm trying something like the following, but this will obviously not work:
List<Table1> result = new List<Table1>();
IQueryable<Table1> query = session.Query<Table1>();
if (value != null) {
query = query.Where(x => x.Table2s.Field == value);
}
query = query.OrderBy(x => x.Id);
result = query.ToList();
I think this is not possible the way you do this. Hibernate loads the complete entity with all its properties (if not lazyloading is activated). What should hibernate do, if you save such a loaded entity of type table1 without all table2's?
You should create some kind of viewobject (dvo) that contains the relevant parts of table1 and a list of table2 childs that fit the criteria. The select could possible be done by projection.