2
EFコアが提供するIQuerableコレクションがいくつかあります。エンティティのSystem.Linq.Expressionsを使用してSQLに変換するための動的クエリを作成します。c#式ツリーを使用して複数のコレクションを照会
IQueryable<ADP> collection1 = _context.Adps;
IQueryable<VHStr> collection2 = _context.VHStrParams;
var q = (from ADP a in collection1
where collection2.Any(p => p.Value.Contains("I") && p.Entid == a.Id)
select a);
var l = q.ToList();
これは正しく機能し、正しいSQLが生成されます。
質問は、どうやって式を使ってそのようなクエリを構築できますか?私はちょうど...私は最初の1の要素のために構築された表現で別のコレクションにアクセスする方法を
EDITを把握することはできません。誰かがそれを見つける場合は、解決策は次のとおりです。
IQueryable<ADP> collection1 = _context.Adps;
IQueryable<VHStr> collection2 = _context.VHStrParams;
var q = (from ADP a in collection1
where collection2.Any(p => p.Value.Contains("I") && p.Entid == a.Id)
select a);
var paramExpA = Expression.Parameter(typeof(ADP), "a");
var paramExpV = Expression.Parameter(typeof(VHStr), "v");
var entIdExp = Expression.PropertyOrField(paramExpV, "Entid");
var adpIdExp = Expression.PropertyOrField(paramExpA, "Id");
var convertedAdpIdExp = Expression.Convert(adpIdExp, typeof(long?));
var valueExp = Expression.PropertyOrField(paramExpV, "Value");
var containsStringMethod = typeof(string).GetMethod("Contains", new[] {typeof(string)});
var constValueExp = Expression.Constant("I", typeof(string));
var containsExp = Expression.Call(valueExp, containsStringMethod, constValueExp);
var equalIdsExp = Expression.Equal(entIdExp, convertedAdpIdExp);
var andExp = Expression.AndAlso(containsExp, equalIdsExp);
var lambda1 = Expression.Lambda<Func<VHStr, bool>>(andExp, paramExpV);
var vhstrAnyMethod =
typeof(Queryable)
.GetTypeInfo()
.GetMethods()
.First(m => m.Name == "Any" && m.GetParameters().Count() == 2)
.MakeGenericMethod(typeof(VHStr));
var collection2ConstExpr = Expression.Constant(collection2);
var anyCallExp = Expression.Call(vhstrAnyMethod, collection2ConstExpr, lambda1);
var collection1ConstExpr = Expression.Constant(collection1);
var lambda2 = Expression.Lambda<Func<ADP, bool>>(anyCallExp, paramExpA);
var whereExp = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { typeof(ADP) },
collection1ConstExpr,
lambda2);
var lambda3 = Expression.Lambda<Func<IQueryable<ADP>>>(whereExp);
var resultFunc = lambda3.Compile();
var resultQuerable = resultFunc();
var resultList = resultQuerable.ToList();
をポイントである - 正確にどのように私は条件を追加することができます"p.Entid == a.Id"を 'dynamically_built_predicate_body'に追加しました。 – pushist1y
私はそれが明らかだと思います。 'p'は上記のスニペットの' anyParam'です。 'a'はあなたが作成する別の' ParameterExpression'になります( 'var a = Expression.Parameter(collection1.ElementType、" a ");' 'Where'コール用の述部を生成するために使われます)' anyCall 'p.Entid == a.id'の場合は' Expression.Equal(Expression.PropertyOrField(anyParam、 "Entid")、Expression.PropertyOrField()があります。 (a、 "id"))など。 –
ありがとう、Expression.Constantは正しい方向へのポイントでした。 – pushist1y