在像这样的数据模型(http://alanstorm.com/2009/img/magento-book/eav.png)中,我想使用Linq到SQL从EAV_Attribute获取值。
假设EAV_Attribute只存在于一个继承表(varchar,decimal,int等)中,如何在linq查询中获取它?
我知道我可以使用继承,但我想在SQL数据库端执行它...
考虑到元素有不同的类型,是否可以在Linq中进行一种Coalesce?
答案 0 :(得分:0)
EAV和linq不是幸福的婚姻。我认为您最好的方法是在eav_attribute
中创建一个未映射的属性,该属性可以从其类型属性子元素中解析值(如object
)。使用实体框架,您将无法在表达式中使用此属性(即不在Where
或Select
中),您必须先转换为IEnumerable
才能访问它。 (Linq-to-sql可能允许它,因为它可以切换到引擎盖下面的linq-to-objects)。
另一种选择是创建一个类型为sql_variant
的计算列,该列执行相同的操作,但现在使用t-sql代码。但是...... EF没有支持sql_variant
。您必须使用some trickery来阅读它。
这是阅读部分。
对于设置/修改/删除值,我看不到任何快捷方式。您只需将父对象和子对象作为任何对象图处理对象。在sql server中,您不能使用级联删除,因为它只能为一个外键定义。 (This可以解决这个问题,但我从未尝试过。)
所以,不是真的好消息,我害怕。也许很高兴知道在一个项目中我也使用具有不可避免的EAV部分的数据库。我们也用EF做它,但它不是没有摩擦。
答案 1 :(得分:0)
首先,我建议使用TPH而不是TPT用于EAV表。 (一个表有多个可空值列(每个类型一个)+鉴别器与每个类型一个表。)
无论哪种方式,如果你将值实体建模为一个抽象类(包含两个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。