1

需要在 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<Entity> 属性转换为单个通用 List<T> ,其中 T : BaseEntity,这是否会导致我可以查询特定衍生物的单个查找表?就像是:

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

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

@达斯维德:

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

1 回答 1

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;

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

于 2012-08-22T08:00:15.350 回答