在 LINQ-to-sql 抽象 class 中映射表达式

Mapping expressions in LINQ-to-sql abstract class

我有一个抽象 class 被两个 class 继承。两个 classes 都代表数据库中的表。尽管在抽象 class 中,我在映射表达式时遇到了麻烦,因此我不断收到无法将其转换为 SQL 的异常。我在 Whosebug 中发现的所有问题都在谈论已经为我工作的专栏。

下面是一段非常简单的代码,说明了我的意思。汽车和摩托车具有完全独立的 _isNew 表达式实现。

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 属性,但它运行 Car class 的 _isNew 以防 Vehicle 是 Car 类型。无论如何我可以做到这一点吗?我尝试过的所有解决方案都导致无法转换为 SQL.

的异常

抽象class允许你强制继承class来实现你的IsNew属性。它只是一个基础class。 您必须使用 Car 或 Motorcycle 的实现,为此,您应该将 Vehicule 对象转换为 Car 或 Motorcycle,以便调用正确的 IsNew 属性。

var vehicule = new Car();

在我回答你的问题之前,你应该检查一下 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 服务器中作为 computed column, 我个人认为这是你最好的选择。