【问题标题】:EAV - Get value using Linq to entitiesEAV - 使用 Linq 到实体获取价值
【发布时间】:2012-11-22 10:00:06
【问题描述】:

在这样的数据模型中 (http://alanstorm.com/2009/img/magento-book/eav.png),我想使用 Linq to SQL 从 EAV_Attribute 中获取值。

假设 EAV_Attribute 仅存在于一个继承表(varchar、decimal、int 等)中,我如何在 linq 查询中获取它?

我知道我可以为此使用继承,但我想在 SQL 数据库端执行它...

考虑到元素有不同的类型,是否可以在 Linq 中做一种 Coalesce?

【问题讨论】:

  • 假设您使用 C# 构建您的 LINQ to SQL 查询,您可以将空合并运算符 (??) 与外部连接一起使用。试一试!
  • 我已经尝试过了,但我做不到,因为“Value”属性在每个表中都有不同的数据类型。
  • 如果您使用的是实体框架,那么您使用的是 LINQ to Entities,而不是 LINQ to SQL(Microsoft 宣布终止使用的不同技术)。
  • 另外,您所说的“我知道我可以使用继承”是什么意思?为什么您认为这会阻止查询被转换为 SQL?

标签: linq entity-framework linq-to-entities entity-attribute-value


【解决方案1】:

EAV 和 linq 的婚姻并不幸福。我认为你最好的办法是在eav_attribute 中创建一个未映射的属性,从它的类型属性子项中解析值(如object)。使用实体框架,您将无法在表达式中使用此属性(即不在WhereSelect 中),您必须先转换为IEnumerable 才能访问它。 (Linq-to-sql 可能允许这样做,因为它可以在底层切换到 linq-to-objects)。

另一个选项是创建一个 sql_variant 类型的计算列,它的作用相同,但现在在 t-sql 代码中。但是... EF 不支持sql_variant。你必须使用some trickery 来阅读它。

这是阅读部分。

对于设置/修改/删除值,我没有看到任何快捷方式。您只需将对象作为具有父母和孩子的任何对象图来处理。在 sql server 中,您不能使用级联删除,因为它只能为一个外键定义。 (This 可能会解决这个问题,但我从未尝试过)。

所以,恐怕不是什么好消息。也许很高兴知道在一个项目中,我还使用具有不可避免的 EAV 部分的数据库。我们也用 EF 来做这件事,但也不是没有摩擦。

【讨论】:

    【解决方案2】:

    首先,我建议对 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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-02
      • 1970-01-01
      相关资源
      最近更新 更多