如何在EF Core表达式中使用继承的属性? [英] How to use inherited properties in EF Core expressions?

查看:191
本文介绍了如何在EF Core表达式中使用继承的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们需要以动态方式构造EF的表达式。例如,创建测试模型:

We need construct expression for EF in dynamic way. For example create test models:

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表达式,并且始终具有属性的字符串名称,因此我们尝试了构造

We require create expression from any type and always we have a string name of property, thus we tried construct it in this way:

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

Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryCompilationContextFactory[8] The LINQ expression '(new TestCard() {Id = [card].disp_CardID, Guid = [card].Guid}.Id == 1030)' could not be translated and will be evaluated locally. To configure this warning use the DbContextOptionsBuilder.ConfigureWarnings API (event id 'RelationalEventId.QueryClientEvaluationWarning'). ConfigureWarnings can be used when overriding the DbContext.OnConfiguring method or using AddDbContext on the application service provider.

我们在分析器中检查了产生的SQL,并得到以下结果:
q.Where(ex1).ToList();内置到

We checked resulting SQL in profiler and got this results: q.Where(ex1).ToList(); built to

SELECT [card].[disp_CardID], [card].[Guid]
FROM [hlt_disp_Card] AS [card]
WHERE [card].[disp_CardID] = 1030

和q。 Where(ex2).ToList();内置到

and q.Where(ex2).ToList(); built to

SELECT [card].[disp_CardID], [card].[Guid]
FROM [hlt_disp_Card] AS [card]

如果我尝试为非继承构建过滤器属性(例如Guid)运作良好!

And if I try construct filter for not-inherited property (eg Guid) my way works well!

EF核心版本:1.0.1

EF Core version: 1.0.1

如何解决

推荐答案

哇,这听起来像是另一个EF Core错误(在v.1.1.0(发行版)中也是如此) 。

Wow, this sounds like another EF Core bug (happens also in v.1.1.0 (release)).

两个表达式之间的唯一区别是 ReflectedType 的属性访问表达式 成员

The only difference between the two expressions is the ReflectedType of the property accessor expression Member.

您可以通过以下方式解决它:

You can fix it this way:

// ...
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

but it's weird to have such requirement, I would suggest reporting the issue to EF Core GitHub.

这篇关于如何在EF Core表达式中使用继承的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆