在 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, 我个人认为这是你最好的选择。
我有一个抽象 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, 我个人认为这是你最好的选择。