ICriteria,加限制收集的内容
-
26-09-2019 - |
题
使用它能够我想要得到获得的列表B的其中一个IList财产的B包含一个具体实例A
以下代码应该有希望解释的情况更清楚:
public void test()
{
A a1 = new A();
A a2 = new A();
B b1 = new B();
b1.As = new List<A> { a1 };
// ...database save cut...
using (ISession session = SessionFactory.OpenSession())
{
var result1 = session.CreateCriteria<B>()
.CreateAlias("As", "a_As")
.Add(Restrictions.Eq("a_As.ID", a1.ID))
.List();
var result2 = session.CreateCriteria<B>()
.CreateAlias("As", "a_As")
.Add(Restrictions.Eq("a_As", a1))
.List();
}
}
class A
{
public virtual int ID { get; set; }
}
class B
{
public virtual IList<A> As { get;set;}
}
第二个查询失败的错误: could not resolve property: a_As of: B
我怎么能执行这种查询使用对象的情况下,没有明确使用ID属性,如在第一个查询以上。
编辑:扩大这,我有一个通用的级执行它能够动用我的实体。我刚创建了一个"IsReferenced"方法的开头如下:
public bool IsReferenced(T entity)
{
// Get the types (and their properties) that reference the type in question
var typeProps = from type in typeof(T).Assembly.GetTypes()
let props = type.GetProperties().Where(p => p.PropertyType == typeof(T)).Select(p => p.Name)
let collections = type.GetProperties().Where(p => typeof(IEnumerable<T>).IsAssignableFrom(p.PropertyType)).Select(p => p.Name)
where type.IsClass && !type.IsAbstract && ((props != null && props.Count() > 0) || (collections != null && collections.Count() > 0))
select new { EntityType = type, Properties = props, Collections = collections };
var multiCriteria = NHibernateSession.CreateMultiCriteria();
foreach (var typeProp in typeProps)
{
var criteria = NHibernateSession.CreateCriteria(typeProp.EntityType);
var disjunction = new Disjunction();
foreach (var propName in typeProp.Properties)
{
disjunction.Add(Restrictions.Eq(propName, entity));
}
foreach (var collectionName in typeProp.Collections)
{
throw new NotImplementedException();
}
criteria.Add(disjunction);
multiCriteria.Add(criteria);
}
.....
}
我使用的typeProps建立一个多准则找到任何实体任何地方引用的一个指定。它的工作的现用正常的性能,但收集的属性是给我的悲伤。我不知道该如何去关于增加限制的进入标准。
解决方案 2
我已经找到一个解决方案,似乎工作的我的前的实体,基于两条信息我已经脱脂过,同时在这方面的工作:
- 该文件的国家较低的情况下'id'是一个特殊属性,可用于参照的id的任何实体。
- ISession公开的公共方法
object ISession.GetIdentifier(object obj)
这两个花絮让我们做这样的事情:
var result2 = session.CreateCriteria<B>()
.CreateAlias("As", "a_As")
.Add(Restrictions.Eq("a_As.id", session.GetIdentifier(a1)))
.List();
和所得IsReferenced方法看起来是这样的:
public bool IsReferenced(T entity)
{
// Get the types (and their properties) that reference the type in question
var typeProps = from type in typeof(T).Assembly.GetTypes()
let props = type.GetProperties().Where(p => p.PropertyType == typeof(T)).Select(p => p.Name)
let collections = type.GetProperties().Where(p => typeof(IEnumerable<T>).IsAssignableFrom(p.PropertyType)).Select(p => p.Name)
where type.IsClass && !type.IsAbstract && ((props != null && props.Count() > 0) || (collections != null && collections.Count() > 0))
select new { EntityType = type, Properties = props, Collections = collections };
var multiCriteria = NHibernateSession.CreateMultiCriteria();
// Create a big or query to test whether any of the properties are, or contain, the entity parameter
foreach (var typeProp in typeProps)
{
var criteria = NHibernateSession.CreateCriteria(typeProp.EntityType);
var disjunction = new Disjunction();
foreach (var propName in typeProp.Properties)
{
disjunction.Add(Restrictions.Eq(propName, entity));
}
foreach (var collectionName in typeProp.Collections)
{
string alias = string.Format("a_{0}", collectionName);
criteria.CreateAlias(collectionName, alias, NHibernate.SqlCommand.JoinType.LeftOuterJoin);
disjunction.Add(Restrictions.Eq(string.Format("{0}.id", alias), NHibernateSession.GetIdentifier(entity)));
}
criteria.Add(disjunction);
multiCriteria.Add(criteria);
}
var results = multiCriteria.List();
bool hasReferences = false;
foreach (var resultSet in results)
{
if ((resultSet as System.Collections.IList).Count != 0)
{
hasReferences = true;
break;
}
}
return hasReferences;
}
如果只有我的大脑已经开始之前,我把一半的我的声誉作为一个赏金...
其他提示
这个类型的查询被更好地服务HQL比标准:
session.CreateQuery("from B b where :a in elements(b.As)")
.SetParameter("a", a1)
.List();
不隶属于 StackOverflow