[英]How to use inherited properties in EF Core expressions?
我們需要以動態方式構造EF的表達。 例如,創建測試模型:
public class TestBase
{
public int Id { get; set; }
}
public class TestCard : TestBase
{
public Guid Guid { get; set; }
}
創建一個linq查詢:
var q = from card in Context.hlt_disp_Card
select new TestCard
{
Id = card.disp_CardID,
Guid = card.Guid
};
正常使用表達式:
Expression<Func<TestCard, bool>> ex1 = card => card.Id == 1030;
q.Where(ex1).ToList();
我們需要使用任何類型的create表達式,並且始終具有屬性的字符串名稱,因此我們嘗試以這種方式構造它:
var e = Expression.Parameter(typeof(TestCard), "card");
Expression bin = Expression.Property(e, "Id");
bin = Expression.Equal(bin, Expression.Constant(1030));
var ex2 = Expression.Lambda<Func<TestCard, bool>>(bin, e);
q.Where(ex2).ToList();
但是我們得到了警告:
Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryCompilationContextFactory [8] LINQ表達式'(new TestCard(){Id = [card] .disp_CardID,Guid = [card] .Guid} .Id == 1030)'無法翻譯並且將在本地進行評估。 要配置此警告,請使用DbContextOptionsBuilder.ConfigureWarnings API(事件ID為'RelationalEventId.QueryClientEvaluationWarning')。 重寫DbContext.OnConfiguring方法或在應用程序服務提供程序上使用AddDbContext時,可以使用ConfigureWarnings。
我們在探查器中檢查了生成的SQL並得到了以下結果:q.Where(ex1).ToList(); 建於
SELECT [card].[disp_CardID], [card].[Guid]
FROM [hlt_disp_Card] AS [card]
WHERE [card].[disp_CardID] = 1030
和q.Where(ex2).ToList(); 建於
SELECT [card].[disp_CardID], [card].[Guid]
FROM [hlt_disp_Card] AS [card]
如果我嘗試為非繼承屬性(例如Guid)構造過濾器,我的方法會很好!
EF核心版本:1.0.1
如何解決這個問題呢?
哇,這聽起來像是另一個EF Core錯誤(在v.1.1.0(發行版)中也會發生)。
兩個表達式之間的唯一差別是ReflectedType
屬性訪問表達的Member
。
您可以通過以下方式解決它:
// ...
var p = e.Type.GetProperty("Id");
if (p.ReflectedType != p.DeclaringType)
p = p.DeclaringType.GetProperty(p.Name);
Expression bin = Expression.MakeMemberAccess(e, p);
// ...
但是有這樣的要求很奇怪,我建議將問題報告給EF Core GitHub 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.