在这样的数据模型(http://alanstorm.com/2009/img/magento-book/eav.png)中,我想使用 Linq to SQL 从 EAV_Attribute 中获取值。
假设 EAV_Attribute 仅存在于一个继承表(varchar、decimal、int 等)中,我如何在 linq 查询中获取它?
我知道我可以为此使用继承,但我想在 SQL 数据库端执行它......
考虑到元素具有不同的类型,是否可以在 Linq 中进行一种合并?
在这样的数据模型(http://alanstorm.com/2009/img/magento-book/eav.png)中,我想使用 Linq to SQL 从 EAV_Attribute 中获取值。
假设 EAV_Attribute 仅存在于一个继承表(varchar、decimal、int 等)中,我如何在 linq 查询中获取它?
我知道我可以为此使用继承,但我想在 SQL 数据库端执行它......
考虑到元素具有不同的类型,是否可以在 Linq 中进行一种合并?
首先,我建议对 EAV 表使用 TPH 而不是 TPT。(一个表有多个可空值列(每种类型一个)+ 鉴别器与每种类型一个表。)
无论哪种方式,如果您将值实体建模为一个抽象类(包含两个 ID),每个值数据类型都有一个继承实体,添加了 value 属性,那么您的 LINQ 应该如下所示:
var valueEntity = context.ProductAttributes.Where(pa =>
pa.ProductId == selectedProductId
&& pa.AttributeTypeId == selectedAttributeTypeId)
.SingleOrDefault() as ProductAttributeOfDouble;
if valueEntity != null
return valueEntity.Value;
return null;
其中实体类型为:Product、AttributeType、ProductAttribute、ProductAttributeOfDouble、... ProductAttributeOfString。
EAV 和 linq 的婚姻并不幸福。我认为你最好的办法是创建一个未映射的属性,从它的类型属性子项eav_attribute
中解析值(as )。object
使用实体框架,您将无法在表达式中使用此属性(即不在 a Where
or中Select
),您必须先转换为IEnumerable
才能访问它。(Linq-to-sql 可能允许它,因为它可以在底层切换到 linq-to-objects)。
sql_variant
另一种选择是创建一个类型相同的计算列,但现在在 t-sql 代码中。但是... EF 不支持sql_variant
. 你必须使用一些技巧来阅读它。
那就是阅读部分。
对于设置/修改/删除值,我没有看到任何快捷方式。您只需将对象作为具有父母和孩子的任何对象图来处理。在 sql server 中,您不能使用级联删除,因为它只能为一个外键定义。(这可能会解决这个问题,但我从未尝试过)。
所以,恐怕不是什么好消息。也许很高兴知道在一个项目中,我还使用具有不可避免的 EAV 部分的数据库。我们也使用 EF 来做到这一点,但并非没有摩擦。