ICriteria、追加の制限収集内容
-
26-09-2019 - |
質問
利用設定によりどちらのモようにしている取得のリストを取得するのでは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をMultiCriteria加者主体のものを参照するのを指定します。での動作のための通常の特性が、収特性を与えてくれた悲しみなんなのかについての添加による制限の基準とします。
解決 2
がその場で発音を確認することが解決される作業のためのすべての私の現在の主体は、二つの情報ん脱脂えながら作:
- 文書とする場合が'id'の特性を参照するために使うことができるidの団体をいう。
- ISession公開メソッドは、publicメソッド
object ISession.GetIdentifier(object obj)
これら二つのtitbitsういうようになります:
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