gpt4 book ai didi

c# - 创建参数等于对象的 LINQ 表达式

转载 作者:IT王子 更新时间:2023-10-29 04:39:34 26 4
gpt4 key购买 nike

给定原始值 age 我知道如何创建这样的表达式:

//assuming: age is an int or some other primitive type
employee => employee.Age == age

这样做:

var entityType = typeof(Employee);
var propertyName = "Age";
int age = 30;
var parameter = Expression.Parameter(entityType, "entity");

var lambda = Expression.Lambda(
Expression.Equal(
Expression.Property(parameter, propertyName),
Expression.Constant(age)
)
, parameter);

除了在所讨论的属性和常量不是原始类型的情况下,它工作正常。

如果是对象之间的比较,我将如何构造相似的表达式?

使用 EF 我可以写:

Location location = GetCurrentLocation();
employees = DataContext.Employees.Where(e => e.Location == location);

这也有效,但如果我尝试创建相同的表达式:

var entityType = typeof(Employee);
var propertyName = "Location";
var location = GetCurrentLocation();
var parameter = Expression.Parameter(entityType, "entity");

var lambda = Expression.Lambda(
Expression.Equal(
Expression.Property(parameter, propertyName),
Expression.Constant(location)
)
, parameter);

我收到一条错误消息:

无法创建“位置”类型的常量值。在此上下文中仅支持原始类型或枚举类型。

我怀疑 Expression.Constant() 只需要原始类型,所以我需要使用不同的表达式工厂方法。 (可能是Expression.Object?-我知道那不存在)

有没有办法创建一个比较对象的表达式?为什么 EF 能够正确解释编译后的 LINQ 语句,但当它是表达式时却不能?

最佳答案

除了前面回答中提到的内容。一个更具体的解决方案是这样的:

public static Expression CreateExpression<T>(string propertyName, object valueToCompare)
{
// get the type of entity
var entityType = typeof(T);
// get the type of the value object
var valueType = valueToCompare.GetType();
var entityProperty = entityType.GetProperty(propertyName);
var propertyType = entityProperty.PropertyType;


// Expression: "entity"
var parameter = Expression.Parameter(entityType, "entity");

// check if the property type is a value type
// only value types work
if (propertyType.IsValueType || propertyType.Equals(typeof(string)))
{
// Expression: entity.Property == value
return Expression.Equal(
Expression.Property(parameter, entityProperty),
Expression.Constant(valueToCompare)
);
}
// if not, then use the key
else
{
// get the key property
var keyProperty = propertyType.GetProperties().FirstOrDefault(p => p.GetCustomAttributes(typeof(KeyAttribute), false).Length > 0);

// Expression: entity.Property.Key == value.Key
return Expression.Equal(
Expression.Property(
Expression.Property(parameter, entityProperty),
keyProperty
),
Expression.Constant(
keyProperty.GetValue(valueToCompare),
keyProperty.PropertyType
)
);
}
}

要点:

  1. 确保检查空值
  2. 确保 propertyTypevalueType 兼容(它们是同一类型或可转换)
  3. 这里做了几个假设(例如,您确实分配了一个 KeyAttribute)
  4. 此代码未经测试,因此不能完全复制/粘贴。

希望对您有所帮助。

关于c# - 创建参数等于对象的 LINQ 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15977908/

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