【问题标题】:EF 4.1 Generic Many-To-Many relationshipEF 4.1 通用多对多关系
【发布时间】:2012-08-21 23:15:57
【问题描述】:

需要在 EF 4.1 中构建各种标记系统,允许查询每个标签的所有实体,或每个实体的所有标签。这是我的模型的简短快照:

public abstract class BaseEntity {

    [Required]
    [Key]
    public Guid ID { get; set; }
}

public class Tag : BaseEntity {
    // tag subscribers
    public List<King> Kings { get; set; }
    public List<Knight> Knights { get; set; }
    public List<Peasant> Peasants { get; set; }
}

public class King : BaseEntity {
    public string Title { get; set; }
    public List<Tag> Tags { get; set; }
}

public class Knight : BaseEntity {
    public string Title { get; set; }
    public List<Tag> Tags { get; set; }
}

public class Peasant : BaseEntity {
    public string Title { get; set; }
    public List<Tag> Tags { get; set; }
}

(是的,我知道国王、骑士和农民在这里是一样的。但正如信使在巨蟒与圣杯中所说:“这只是一个模型。”)

所以无论如何,这个模型工作得很好,但我更喜欢 T 通用列表,而不是特定的演员表。数据库中的表更少,从标签到实体查询时的开销更少。如何将 Tag 中的所有 List 属性转换为单个通用 List ,其中 T : BaseEntity,这是否会导致我可以查询特定衍生物的单个查找表?比如:

 List<Knight> knightsByTag = Tags.Where(t => t.GetType() == typeof (Knight)).ToList();

编辑: 是的。抱歉,里面还有一些实际的代码。

@DarthVader:

  • 希望 Tag 使用一个 List 属性,而不是当前的三个 List 属性。
  • 希望能够查询与骑士关联的所有标签,或与标签关联的所有农民等。
  • 希望确保 EF CodeFirst 能够准确解析通用列表,最好使用查找表。

【问题讨论】:

  • 你能澄清和简化你的问题吗?你想查询什么? Tags 没有您定义的 Knight。你怎么写最后一个查询?

标签: c# .net generics entity-framework-4 ef-code-first


【解决方案1】:

如果您想在 BaseEntity 中拥有单个列表,您还必须将列表放入子实体中。你会以这样的方式结束:

public abstract class BaseEntity {
    ...

    // tags
    public List<Tag> Tags { get; set; }
}

public class Tag : BaseEntity {
    ...

    // tag subscribers
    public List<BaseEntity> Entities { get; set; }
}

如果您有任何特定约束,您必须在实体和标签之间建立关系之前在应用程序中检查它们。任何其他方式都会导致您将每个实体的导航属性和每个此类关系的连接表分开。

与骑士相关的所有标签 - 这应该有效:

var tags = from k in context.Knights // or context.BaseEntities.OfType<Knight>()
           from t in k.Tags
           select t;

与标签关联的所有农民 - 这应该可以:

var peasants = from t in context.Tags
               from p in t.Entities.OfType<Peasant>()
               select p;

注意映射继承对查询性能有负面影响。

【讨论】:

  • 感谢您的回复。我担心&lt;BaseEntity&gt; 包含衍生的集合...Tag(例如List&lt;T&gt; where T : BaseEntity)中的通用集合不可行吗?
  • 抱歉延迟回复。拉迪斯拉夫,你的答案不是我想要的,但那是因为我正在寻找的东西并不可行。所以你的答案在技术上是正确的。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2011-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多