[英]Using Dynamic LINQ Where in a one-to-many Entity Framework relationship
我使用的是EF 6和.net 4.5。 我有一個帶有PK“DocumentId”(Int)的“Documents”表和另一列“Title”。 我有另一個名為“DocumentFilters”的表,其中包含“DocumentId”(Int)和“DocGUID”(Guid)列。 兩個表之間的“Doc Id”上有一個FK。 它是Documents和DocumentFilters表之間的一對多Id關系。 模型看起來像這樣:
我正在嘗試使用NuGet包中的DynamicLibrary.cs庫編寫動態LINQ查詢。
使用常規Linq,查詢在c#中看起來像這樣:
DocDBContext db = new DocDBContext();
var documents = db.Documents.Include(d => d.DocumentFilters);
Guid gTest = Guid.Parse("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");
documents = documents.Where(d => d.DocumentFilters.Select(f => f.DocGUID).Contains(gTest));
這非常有效並且檢索由我感興趣的GUID過濾器分隔的文檔。但是,我需要動態地將它放在過濾器字符串中,其中它可能包含其他過濾器。 有可能嗎? 我嘗試過的代碼如下:
documents = documents.Where("DocumentFilters.Select(DocGUID).Contains(@0)", gTest);
錯誤:不存在適用的聚合方法“選擇”
要么
documents = documents.Where("DocumentFilters.DocGUID=@0", gTest);
錯誤:DocumentFilters上不存在GUID屬性。 (這是有道理的,因為DocumentFilters是一個集合)。
我也認為值得這樣做:
documents = documents.Where("DocumentFilters.AsQueryable().Select(DocGUID).Contains(@0)", gTest);
但同樣,它看起來不像庫支持AsQueryable並拋出錯誤:沒有適用的聚合方法'AsQueryable'存在。
是否可以在Documents表中對可枚舉對象的屬性寫入這樣的限制?
因此,一種解決方案是通過向ExpressionParser
類中的IEnumerableSignatures
接口添加“ Select ”來修改Dynamic.cs。 另外將它添加到ParseAggregate()
方法:
if (signature.Name == "Min" || signature.Name == "Max")
{
typeArgs = new Type[] { elementType, args[0].Type };
}
else if (signature.Name == "Select")
{
typeArgs = new Type[] { elementType, Expression.Lambda(args[0], innerIt).Body.Type };
}
但是,在此之后我仍然需要重載Contains()
方法以使用GUID。 我沒那么費心。 相反,我意識到我可以簡單地使用已經支持的.Any()
而不是.Select()
!
documents = documents.Where("DocumentFilters.Any(DocGUID.Equals(@0))", gTest); //!!!
我還必須將列名從“ GUID ”更改為“ DocGUID ”,因為在限制字符串中寫入GUID.Equals()
時,解析器將其誤認為是GUID類型而不是列名,並拋出了Equals()
的錯誤Equals()
不是GUID類型的有效擴展名。
很抱歉浪費每個人的時間!
嘗試使用Dynamic Linq ,它可以用於對抗字符串。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.