问题
I have a mapped class that has a ICollection property which is mapped as a Set (using by code mappings). Note that the collection contains strings and not another mapped entity. e.g.
public class Item
{
public virtual ICollection<string> Facts { get; set; }
}
public class ItemMapping
{
public ItemMapping()
{
Set(x => x.Facts, m =>
{
m.Key(k => k.Column("ItemId"));
m.Table("Facts");
}, col => col.Element(m =>
{
m.Column("Description");
m.Type(NHibernateUtil.String);
}));
}
}
This works and CRUD operations on Items with Facts works fine.
However, I want to QueryOver<> the Facts in the database (e.g. retrieve the count or first 20 facts or retrieve some random facts) but given there is no entity how do I do this? I don't want to introduce a Fact entity because the only property it would have would be a string.
回答1:
Well, my suggestion would be:
introduce entity. Even if it would have only one property. Later you can extend that (with Order, IsVisible). And if you will do that everywhere your framework will be built only from
one-to-many
andmany-to-one
relations among first citizens objects. That mean simple "framework generalization, reuse..."
But I see that you do not like it (please, at least try to re-think) - so there is the way:
NHibernate How do I query against an IList property?
Where I tried to show that (based on the documentation) we can use magical word ".elements"
:
17.1.4.1. Alias and property references
So the query which will touch the string elements in your case
Item item = null;
string fact = null;
var demos = session.QueryOver<Item>(() => item)
.JoinAlias(i => i.Facts, () => fact)
// instead of this
// .Add(Restrictions.Eq("fact", "abc"))
// we can use the .elements keyword
.Where(Restrictions.Eq("fact.elements", "abc"))
.List<Item>();
So, this way, you can get Items which do have some facts equal to "abc"
回答2:
non entities have to be queried by their entities and selected then. For example to get the first 20 facts:
string fact = null;
var first20facts = session.QueryOver<Item>()
.JoinAlias(i => i.Facts, () => fact)
.OrderBy(() => fact).Asc
.Take(20)
.Select(() => fact)
.List<string>();
Alternativly you could also map a readonly entity for Fact just to query it.
来源:https://stackoverflow.com/questions/27954519/queryover-iliststring-property