gpt4 book ai didi

c# - MethodCallExpression orderby

转载 作者:行者123 更新时间:2023-11-30 12:59:46 30 4
gpt4 key购买 nike

我正在尝试使用表达式树构建一个 lambda 查询,以使其在整个应用程序中通用。我最初的尝试基于找到的代码 here .我更改了代码,以便它执行比较以返回 100 个实体,这些实体的 LastName 就在 searchText 之前,如下所示:

TEntity entity = entitySet.FirstOrDefault();
string searchName = entity.GetType().GetProperty("SearchName").ToString();
searchText = "Baker";
int records = 100;

IQueryable<TEntity> queryableData = entitySet.AsQueryable<TEntity>();
var param = Expression.Parameter(typeof(TEntity), searchName);
var body = Expression.LessThan(Expression.Call(
typeof(string),
"Compare",
null,
Expression.PropertyOrField(param, searchName),
Expression.Constant(searchText)),
Expression.Constant(0));

var lambda = Expression.Lambda<Func<TEntity, bool>>(body, param);

MethodCallExpression whereCallExpression = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { typeof(TEntity) },
queryableData.Expression,
lambda);

var data = entitySet.AsQueryable<TEntity>().Provider.CreateQuery<TEntity>(whereCallExpression).Take(records);

上面的代码有效,它从位于我的 searchText 之前的数据库中返回 100 个实体,但它们是错误的实体,因为它们在 entitySet 中没有按顺序排列。因此,我的表达式树中需要一个 OrderBy 子句,以便我得到“Azure”、Axel、Avis 等。

我试过这个:

 MethodCallExpression orderByCallExpression = Expression.Call(
typeof(Queryable),
"OrderByDescending",
new Type[] { typeof(TEntity), typeof(TEntity) },
whereCallExpression,
Expression.Lambda<Func<TEntity, string>>(param, new ParameterExpression[] { param }));

var data = entitySet.AsQueryable<TEntity>().Provider.CreateQuery<TEntity>(orderByCallExpression).Take(records);

我收到错误消息“System.Core.dll 中出现类型为‘System.ArgumentException’的异常,但未在用户代码中处理

附加信息:类型 MyEntity 的表达式不能用于返回类型“System.String””

堆栈跟踪:

在 System.Linq.Expressions.Expression.ValidateLambdaArgs(类型 delegateType、Expression& body、ReadOnlyCollection`1 参数)

在 System.Linq.Expressions.Expression.Lambda[TDelegate](表达式主体、字符串名称、 bool tailCall、IEnumerable`1 参数)

在 System.Linq.Expressions.Expression.Lambda[TDelegate](表达式主体、 bool tailCall、IEnumerable`1 参数)

所以,我看了here并试过这个:

Expression<Func<TEntity, string>> sortExp = l => l.SearchName);

MethodCallExpression orderByCallExpression = Expression.Call(
typeof(Queryable),
"OrderByDescending",
new Type[] { typeof(TEntity), typeof(string) },
whereCallExpression,
sortExp);

我收到错误消息“mscorlib.dll 中出现类型为‘System.NotSupportedException’的异常,但未在用户代码中处理

其他信息:LINQ to Entities 不支持指定的类型成员“SearchName”。仅支持初始化程序、实体成员和实体导航属性。”

我认为问题在于 SearchName 属性是一个字符串,它包含我想要 OrderBy 的实体上的字段名称。我试过了:

l => (string)l.GetType().GetProperty("SearchName").GetValue(SearchName);

但这给了我错误:“mscorlib.dll 中出现类型为‘System.NotSupportedException’的异常,但未在用户代码中处理

附加信息:LINQ to Entities 无法识别“System.Object GetValue(System.Object)”方法,并且无法将此方法转换为存储表达式。”

TEntity 基于 EntityObject

SearchName 是 TEntity 上的字符串类型的属性,它保存数据库中字段的名称。

entitySet 的类型为 ObjectSet<TEntity>

如有任何建议,我们将不胜感激。

更新和解决方案我找到代码 here这让我想到了不同的方向。以下是用于按 SearchName 进行排序的代码:

var type = typeof(TEntity);
var property = type.GetProperty(searchName);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);

MethodCallExpression orderByCallExpression = Expression.Call(
typeof(Queryable),
"OrderByDescending",
new Type[] { typeof(TEntity), typeof(string) },
whereCallExpression,
Expression.Quote(orderByExp));

var data = entitySet.AsQueryable<TEntity>().Provider.CreateQuery<TEntity>(orderByCallExpression).Take(records);

最佳答案

如果 SearchName 是一个没有存储在你的数据库中的字段,你应该在你的实体模型中忽略它,使用 [ignore] 属性或 this.Ignore(t => t.Property);流畅的 API。

关于c# - MethodCallExpression orderby,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24044924/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com