使用表达式进行手动 Linq-To-Sql 映射是否有效?
我有这个问题:
Vehicle
类型派生自 EntityObject
类型它具有属性“ID”。
我想我明白为什么 L2S 不能将其转换为 SQL - 它不知道 WHERE 子句应该包含 WHERE VehicleId == value
。 VehicleId
顺便说一句,是表上的 PK,而对象模型中的属性(如上所述)是“ID”。
我什至可以用表达式树赢得这个胜利吗?因为创建一个Expression
来传递给SingleOrDefault
方法似乎很容易,但L2S仍然无法翻译它吗?
我试图做到 DDD 友好,所以我不想用 ColumnAttributes 等来装饰我的域模型对象。不过,我很高兴自定义我的 L2S dbml 文件并在我的“中添加表达式助手/其他内容”数据层”,希望让这个 ORM 业务远离我的领域模型。
更新:
我没有在 select 语句中使用对象初始化语法。像这样:
private IQueryable<Vehicle> Vehicles()
{
return from vehicle in _dc
select new Vehicle() { ID = vehicle.VehicleId };
}
我实际上正在使用构造函数,并且从我读到的内容这将导致上述问题。这就是我正在做的事情:
private IQueryable<Vehicle> Vehicles()
{
return from vehicle in _dc
select new Vehicle(vehicle.VehicleId);
}
我知道 L2S 无法从上面的屏幕截图中翻译表达式树,因为它不知道通常从对象初始化语法中推断出的映射。我该如何解决这个问题?我是否需要使用属性绑定构建Expression
?
I have this problem:
The Vehicle
type derives from the EntityObject
type which has the property "ID".
I think i get why L2S can't translate this into SQL- it does not know that the WHERE clause should include WHERE VehicleId == value
. VehicleId
btw is the PK on the table, whereas the property in the object model, as above, is "ID".
Can I even win on this with an Expression tree? Because it seems easy enough to create an Expression
to pass to the SingleOrDefault
method but will L2S still fail to translate it?
I'm trying to be DDD friendly so I don't want to decorate my domain model objects with ColumnAttributes
etc. I am happy however to customize my L2S dbml file and add Expression helpers/whatever in my "data layer" in the hope of keeping this ORM-business far from my domain model.
Update:
I'm not using the object initialization syntax in my select statement. Like this:
private IQueryable<Vehicle> Vehicles()
{
return from vehicle in _dc
select new Vehicle() { ID = vehicle.VehicleId };
}
I'm actually using a constructor and from what I've read this will cause the above problem. This is what I'm doing:
private IQueryable<Vehicle> Vehicles()
{
return from vehicle in _dc
select new Vehicle(vehicle.VehicleId);
}
I understand that L2S can't translate the expression tree from the screen grab above because it does not know the mappings which it would usually infer from the object initialization syntax. How can I get around this? Do I need to build a Expression
with the attribute bindings?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根据进一步的经验,我断定这是不可能的。
当在映射投影中使用参数化向量时,L2S 根本无法创建正确的 WHERE 子句。它是传统 L2S 映射投影中的初始化语法,为 L2S 提供了所需的上下文。
简短的回答 - 使用 NHibernate。
I have decided that this is not possible from further experience.
L2S simply can not create the correct WHERE clause when a parameterized ctor is used in the mapping projection. It's the initializer syntax in conventional L2S mapping projections which gives L2S the context it needs.
Short answer - use NHibernate.
简短的回答:不。
我曾经尝试应用 IQueryable<.IEntity>到 Linq2Sql。我被烧得很厉害。
正如你所说。 L2S(在这方面也是 EF)不知道 ID 映射到 VehicleId 列。您可以通过将 Vehicle.ID 重构为 Vehicle.VehicleID 来解决此问题。 (是的,如果它们同名,它们就可以工作)。但我仍然不推荐它。
将 L2S 与其提供的对象一起使用。在使用 IQueryable 时掩盖一个额外的层......在我看来是不好的(根据我的经验)。
其他方法是在完成 select 语句后执行 .ToList() 。这会将所有车辆加载到您的内存中。然后,您对 Linq 2 对象集合执行 .Where 语句。当然,这不会那么有效,因为 L2S 会处理所有查询并导致更大的内存使用。
长话短说。不要将 Sql IQueryable 与最初设计的对象以外的任何对象一起使用。它只是不起作用(很好)。
Short answer: Don't.
I once tried to apply the IQueryable<.IEntity> to Linq2Sql. I got burned bad.
As you said. L2S (and EF too in this regard) doesn't know that ID is mapped to the column VehicleId. You could get around this by refactoring your Vehicle.ID to Vehicle.VehicleID. (Yes, they work if they are the same name). However I still don't recommend it.
Use L2S with the object it provided. Masking an extra layer over it while working with IQueryable ... is bad IMO (from my experience).
Otherway is to do .ToList() after you have done the select statement. This loads all the vehicles into your memory. Then you do the .Where statment against Linq 2 Object collections. Ofcourse this won't be as effecient as L2S handles all of the query and causes larger memory usage.
Long story short. Don't use Sql IQueryable with any object other than the ones it was originally designed for. It just doesn't work (well).