【发布时间】:2015-08-07 20:26:07
【问题描述】:
我正在尝试创建 Linq to SQL 表达式,以通常允许在两个不同的域实体记录上比较相同的属性。一般的想法是定义需要比较实体上的哪些属性,然后逐一比较这些属性中的每一个以检查是否相等/不相等。我正在通过在域实体上创建表达式来确定需要比较哪些属性:
public class CompareEntityProperty<TEntity> where TEntity : IEntity
{
public Expression<Func<TEntity, object>> EntityPropertyExpression { get; set; }
public Expression<Func<TEntity, TEntity, bool>> Compare
{
get
{
var expression = EntityPropertyExpression;
return (entityA, entityB) => object.Equals(expression.Invoke(entityA), expression.Invoke(entityB));
}
}
}
然后为一个通用实体设置它,我会这样设置它:
public class foo : IEntity
{
public long? bar { get; set; }
}
我会使用:
public class fooCompare
{
public IEnumerable<CompareEntityProperty<foo>> CompareList
{
get
{
return new []
{
new CompareEntityProperty<foo>() { EntityPropertyExpression = entity => entity.bar }
};
}
}
}
我看到的问题似乎与如何使用“对象”作为属性类型来设置属性表达式有关。编译表达式时,它会尝试将属性类型(在本例中为可为空的 long 类型)转换为对象,SQL 不知道该怎么做,我收到如下错误:
无法将类型“System.Nullable`1[[System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]”转换为类型“System.Object”。
当我添加手表并查看实际生成的表达式时,这似乎得到了证实:
entity => 转换(entity.bar)
看起来它正在尝试首先将属性值转换为“对象”类型可以使用的类型,因此出现错误。
首先,我对错误的假设是否正确?有没有解决的办法?有没有办法将属性表达式设置为动态而不是强类型为“对象”?还是有其他方法可以绕过这个问题?
谢谢!
编辑:我正在使用 LinqKit 库,它提供了处理要转换为 SQL 的表达式上的“Invoke”方法调用所需的逻辑。
【问题讨论】:
-
expression.Invoke(entityA)无法编译,因为Expression.Invoke()将表达式作为参数。您是否使用了某种第三方库的扩展方法之类的? -
是的,你是对的。我正在使用 LinqKit 库,它为这些类型的调用提供了功能。
标签: c# sql linq entity-framework