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

查看:35
本文介绍了如何在 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 查询:

Create a linq query:

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();

我们需要从任何类型创建表达式,并且我们总是有一个属性的字符串名称,因此我们尝试以这种方式构造它:

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.

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]

如果我尝试为 not-inherited 属性(例如 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天全站免登陆