Sam*_*ami 11 .net c# linq inheritance .net-3.5
我有一个由两个类继承的抽象类.这两个类都代表数据库中的表.虽然在抽象类中我遇到了映射表达式的麻烦,因此我不断得到它无法转换为SQL的异常.我在Stackoverflow中找到的所有问题都在谈论已经为我工作的列.
下面是一个非常简单的代码,显示了我的意思.汽车和摩托车有完全独立的_isNew Expression实现.
public abstract class Vehicle {
public abstract boolean IsNew;
}
public partial class Car: Vehicle {
public override boolean IsNew {
get { _isNew.Invoke(this); }
}
}
public partial class Motorcycle: Vehicle {
public override boolean IsNew {
get { _isNew.Invoke(this); }
}
}
Run Code Online (Sandbox Code Playgroud)
我希望能够在IQueryable上调用_isNew表达式或IsNew属性,但是如果Vehicle是Car类型,它会运行Car类的_isNew.无论如何我能做到吗?我尝试的所有解决方案都引发了一个异常,它无法转换为SQL.
在我回答你的问题之前,你可能应该检查一下有关异常的 C# 属性的最佳实践。
您可以立即加载列表,然后调用 IsNew 属性,这将消除 Linq-to-SQL 错误。但我知道,如果您依赖 IsNew 来过滤其中的大量数据,这可能会导致性能问题。
我认为您的问题实际上是由于您想使用车辆实例来获取“IsNew”属性。但你根本不能这样做,因为当你尝试使用未映射到列的属性时,linq-to-sql 会合理地抱怨。
那么,如果您无法使用实例,那么下一个最好的办法是什么?
好吧,也许我会选择静态表达
public partial class Motorcycle : Vehicle
{
public static Expression<Func<Vehicle, bool>> IsNew { get { return (v) => v.Age <= 1; } }
}
public partial class Car : Vehicle
{
public static Expression<Func<Vehicle, bool>> IsNew { get { return (v) => v.Age <= 2; } }
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用
var newCars = db.Cars.Where(Car.IsNew).ToList();
var newMotorcycles = db.Motorcycles.Where(Motorcycle.IsNew).ToList();
Run Code Online (Sandbox Code Playgroud)
或者,您可以将逻辑拉到应用程序之外,并在 SQL Server 中将其作为计算列执行,我个人认为这是您的最佳选择。