ごめんなさい。エンティティフレームワーク:混合エンティティの混合述語
私は(LinqKitで)自分のEFモデルを拡張しようとしています。
私は単一のエンティティ式で作業している限り、私は問題はありませんが、混合式で作業したいのであれば、私はちょっと立ち往生しています。例えば
、そのようなソート・オブ・ポストクラス...
partial class vit_post
{
//[...]
public static Expression<Func<vit_post, bool>> HasMetas(IEnumerable<MetaFilter> metaArgs)
{
var resultsInner = PredicateBuilder.True<vit_post>();
resultsInner.And(p=>p.vit_postmeta.Any(pm => (pm.hide == false)));
foreach (var metaArg in metaArgs)
{
var mf = metaArg;
resultsInner.And(p=>p.vit_postmeta.Any(pm => (pm.meta_key == mf.MetaKey && mf.Compare(pm.meta_value))));
if (mf.ChildrenMetaFilters != null)
{
Expression<Func<vit_post, bool>> resultsInner2;
switch (mf.LogicalOperator)
{
case LogicalOperators.AND:
resultsInner2 = PredicateBuilder.True<vit_post>();
resultsInner = resultsInner2.And(HasMetas(mf.ChildrenMetaFilters));
break;
case LogicalOperators.OR:
resultsInner2 = PredicateBuilder.False<vit_post>();
resultsInner = resultsInner2.Or(HasMetas(mf.ChildrenMetaFilters));
break;
}
}
}
return resultsInner;
}
//[...]
}
...表現HasMetasと実体「vit_post」を拡張します。このスニペットを使用
は、私は予想通り、実体のサブセットを取得:
partial class vit_postmeta
{
//[...]
var resultsInner = PredicateBuilder.True<vit_postmeta>();
resultsInner.And(pm => (pm.hide == false));
foreach (var metaArg in metaArgs)
{
var mf = metaArg;
resultsInner.And(pm => (pm.meta_key == mf.MetaKey && mf.Compare(pm.meta_value)));
if (mf.ChildrenMetaFilters != null)
{
Expression<Func<vit_postmeta, bool>> resultsInner2;
switch (mf.LogicalOperator)
{
case LogicalOperators.AND:
resultsInner2 = PredicateBuilder.True<vit_postmeta>();
resultsInner = resultsInner2.And(HasMetas(mf.ChildrenMetaFilters));
break;
case LogicalOperators.OR:
resultsInner2 = PredicateBuilder.False<vit_postmeta>();
resultsInner = resultsInner2.Or(HasMetas(mf.ChildrenMetaFilters));
break;
}
}
}
return resultsInner;
//[...]
}
:
public SearchResults GetResults()
{
var query = dbc.vit_posts.AsExpandable();
//[...]
if (SearchArgs.Metas != null)
{
var postsbycontent = vit_post.HasMetas(SearchArgs.Metas);
outer = Data.Utility.And(outer, postsbycontent);
}
//[...]
query = query.Where(outer);
var searchResults = new SearchResults
{
Items = searchResultsItems
};
return searchResults;
}
をしかし、私はそのような「vit_postmeta」エンティティにこのこの式を移動しようとした場合
私の考えはvit_postで元のメソッドを保持し、そのようにそれを変更することでした:
partial class vit_post
{
//[...]
public static Expression<Func<vit_post, bool>> HasMetas(IEnumerable<MetaFilter> metaArgs)
{
var resultsInner = PredicateBuilder.True<vit_post>();
resultsInner.And(p=>p.vit_postmeta.HasMetas(metaArgs));
return resultsInner;
}
//[...]
}
しかし、私"'vit_postmeta'に 'HasMetas'の定義が含まれておらず、 'vit_postmeta'タイプの最初の引数を受け入れる拡張メソッド 'HasMetas'が見つかりませんでした。"
何かが見つからないのですが、何が見つかりませんか?
UPDATE
私はそれぞれのエンティティ部分クラスにすべての私の表現を実装し、代替ソリューション(とあまりにもおそらく適切なもの)を見つけました。 たとえば、vit_postにはvit_postsのテーブルに関連するすべての式がありましたが、vit_postmetaにはvit_postmetaのテーブルに関連するすべての式があります。
My Searchクラスには、各エンティティごとにプライベートメソッドがあります。ような何か:
private IQueryable<vit_post> QueryPosts()
{
IQueryable<vit_post> queryPosts = VITContext.vit_posts.AsExpandable();
Expression<Func<vit_post, bool>> outerPredicate = PredicateBuilder.True<vit_post>();
if (!_searchArgs.IncludeExpiredPosts)
{
Expression<Func<vit_post, bool>> postsByExpiration = vit_post.ExcludeExpired();
outerPredicate = Data.Utility.And(outerPredicate, postsByExpiration);
}
if (_searchArgs.LocaleCode != null)
{
Expression<Func<vit_post, bool>> postsByLanguage = vit_post.HasLocaleCode(_searchArgs.LocaleCode);
outerPredicate = Data.Utility.And(outerPredicate, postsByLanguage);
}
[...]
}
はその後GetResults()関数は、すべてのこれらのメソッドを呼び出し、それらを結合:
internal string GetResults()
{
IQueryable<vit_post> queryPosts = QueryPosts();
if (_searchArgs.Metas != null)
{
IEnumerable<vit_postmeta> queryMetas = QueryMetas();
queryPosts = from p in queryPosts
join m in queryMetas
on new {id = p.ID, loc = p.locale} equals new {id = m.post_id, loc = m.locale}
select p;
}
}
私は、クエリが動作することができます。この方法で、私はまだこれがわかりませんそれを行う正しい方法。
あなたの英語は "ひどい"と思いますか? – Aducci
Aducci:ときどき:) –
GertArnold:はい、vit_postはvit_postmetaと1-nの関係を持っています(テーブルはWordPressのテーブルに非常に似たデザインです)。 –