c# - 在反射(reflect)的导航属性上添加排序

标签 c# sql-server entity-framework reflection

我正在使用 EF 6.0 .NET-Framework 和 MS SQL Sever,我遇到以下情况:我在给定实体的导航属性上有一个动态数据选择。到目前为止,这工作正常。但是:我喜欢添加一些排序。但我无法弄清楚如何让 EF 理解,排序应该发送到数据库,而不是之后在客户端排序。 问题似乎是,当我检索导航属性的值时而不是当我使用排序完成命令链时从数据库请求数据。

我的代码是这样的(简单化):

var dynamicRelatedEntityType = typeof(RelatedEntity);

using (var dbContext = new DBContext())
{
    var orderByFunction = buildOrderByFunction(dynamicRelatedEntityType ); // this just builds a function for the order by ...
    var masterEntity = dbContext.MasterEntity.first(x=> x.Whatever = true);
    var navigationProperty = masterEntity.GetType().GetProperty(dynamicRelatedEntityType.Name); 

    var result = navigationProperty.GetValue(masterEntity).OrderBy(orderByFunction).ToList();

    // result is OK, but sort wasn't sent to data base ... it was done by my program which is quite time expensive and silly too ...
}

那么,我该如何改变这种行为,有什么想法吗? 提前致谢!

编辑 为这个问题提供的解决方案解决了动态谓词,但如果您仍然使用navigationProperty.GetValue(masterEntity),则无法应用它们。在这种情况下,EF 将在没有任何顺序或 where 子句的情况下立即触发 SQL ...

最佳答案

您的数据库服务器只能处理 TSQL 语句。 Entity Framework (特别是 Entity Framework 的 SQL Server 插件)能够在有效的 TSQL 中转换一小部分 C# 表达式(在您的情况下为 order by 语句)。

当您的表达式过于复杂(例如调用方法、更改状态)而无法转换为 TSQL 时, Entity Framework 将求助于内存操作。

如果您使用的是 .NET Core,则可以在注册内容时使用以下片段来找出在内存中执行的所有“不受支持”的语句。

var builder = new DbContextOptionsBuilder<MyContext>();
var connectionString = configuration.GetConnectionString("DefaultConnection");
builder.UseSqlServer(connectionString);

// the following line is the one that prevents client side evaluation
builder.ConfigureWarnings(x => x.Throw(RelationalEventId.QueryClientEvaluationWarning));

请注意,在涉及自定义表达式时理解这一点很重要,LINQ 需要静态表达式来推断顺序。但是,您可以按照 LINQ Dynamic Expression Generation 的建议生成动态表达式.尽管我从未尝试过所描述的方法,但在我看来这是实现您所要求的可行方法。

关于c# - 在反射(reflect)的导航属性上添加排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51395589/

相关文章:

c# - ObjectContext 的 SetTransactionHandler

c# - 类型未映射 Entity Framework 5.0

c# - 如何使用SqlCacheDependency?

c# - WebAPI 中未达到带有 FormData 的 HTTP Post

sql - SQL Service Broker:收集数据-插件方案分析

PHP MySql MsSql 如何插入或更新一个 ['] or ["] 或 [`] 字符?

c# - 如何在 LINQ 中按子集合值进行选择

c# - 分配动画后角色位置移动

c# - 如何在不迁移的情况下生成身份数据库脚本

sql - 创建用户定义函数来转换 SQL Server 中的日期