我有一个由两个类继承的抽象类。这两个类都代表数据库中的表。虽然在抽象类中我遇到了映射表达式的麻烦,因此我不断得到它无法转换为SQL的异常。我在Stackoverflow中找到的所有问题都在谈论已经为我工作的列。
下面是一个非常简单的代码,显示了我的意思。 Car和Motorcycle完全独立了_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); }
}
}
我希望能够在IQueryable上调用_isNew表达式或IsNew属性,但是如果Vehicle类型为Car,则它会运行Car类的_isNew。无论如何我能做到吗?我尝试的所有解决方案都引发了一个异常,它无法转换为SQL。
答案 0 :(得分:1)
在我提出您的问题之前,您应该查看best practices of C# properties concerning exceptions。
您可以急切地加载列表,然后再调用您的IsNew属性,这将消除Linq-to-SQL错误。但据我所知,如果依靠IsNew过滤掉大量数据,可能会导致性能问题。
我认为你的问题实际上是由于你想要使用车辆的实例来获得" IsNew"属性。但你根本无法做到,因为linq-to-sql会合理地抱怨when you are trying to use a property that is not mapped to a column。
所以如果你不能使用实例,那么什么是下一个最好的东西?
好吧,也许我会选择静态表达
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; } }
}
你可以使用
var newCars = db.Cars.Where(Car.IsNew).ToList();
var newMotorcycles = db.Motorcycles.Where(Motorcycle.IsNew).ToList();
或者你可以在你的应用程序外面拉逻辑在SQL Server中作为computed column 执行,我个人认为这是你最好的选择。< / p>
答案 1 :(得分:0)
抽象类允许您强制继承的类来实现您的IsNew属性。它只是一个基类。 您必须使用Car或Motorcycle的实现,为此,您应将Vehicule对象转换为Car或Motorcycle,以便调用正确的IsNew属性。
var vehicule = new Car();