C# EF 4.1通用多对多关系

C# EF 4.1通用多对多关系,c#,.net,generics,entity-framework-4,ef-code-first,C#,.net,Generics,Entity Framework 4,Ef Code First,需要在EF4.1中构建一个分类标记系统,该系统允许查询每个标记的所有实体,或每个实体的所有标记。以下是我的模型的简要快照: public abstract class BaseEntity { [Required] [Key] public Guid ID { get; set; } } public class Tag : BaseEntity { // tag subscribers public List<King> Kings {

需要在EF4.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; }
}
公共抽象类BaseEntity{
[必需]
[关键]
公共Guid ID{get;set;}
}
公共类标记:BaseEntity{
//标签订户
公共列表{get;set;}
公开列表骑士{get;set;}
公共列表{get;set;}
}
公共类King:BaseEntity{
公共字符串标题{get;set;}
公共列表标记{get;set;}
}
公共类:BaseEntity{
公共字符串标题{get;set;}
公共列表标记{get;set;}
}
公营农民:基本实体{
公共字符串标题{get;set;}
公共列表标记{get;set;}
}
(是的,我知道国王、骑士和农民在这里都是一样的。但正如信使在《巨蟒山》和《圣杯》中所说:“这只是一个模型而已。”)

所以不管怎样,这个模型工作得很好,但我更喜欢T通用列表,而不是特定的类型转换。数据库中的表越少,从标记到实体的查询开销越小。如何将标记中的所有列表属性转换为一个通用列表,其中T:BaseEntity,这会导致一个查找表,我可以查询特定的派生项?比如:

 List<Knight> knightsByTag = Tags.Where(t => t.GetType() == typeof (Knight)).ToList();
public abstract class BaseEntity {
    ...

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

public class Tag : BaseEntity {
    ...

    // tag subscribers
    public List<BaseEntity> Entities { get; set; }
}
List knightsByTag=Tags.Where(t=>t.GetType()==typeof(Knight)).ToList();
编辑: 是的。抱歉,有些实际代码仍在那里

@DarthVader:

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

如果您想在
BaseEntity
中有一个列表,您还必须删除子实体中的列表。您将以以下内容结束:

 List<Knight> knightsByTag = Tags.Where(t => t.GetType() == typeof (Knight)).ToList();
public abstract class BaseEntity {
    ...

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

public class Tag : BaseEntity {
    ...

    // tag subscribers
    public List<BaseEntity> Entities { get; set; }
}
公共抽象类BaseEntity{
...
//标签
公共列表标记{get;set;}
}
公共类标记:BaseEntity{
...
//标签订户
公共列表实体{get;set;}
}
如果您有任何特定的约束,在建立实体和标记之间的关系之前,您必须在应用程序中检查它们。任何其他方法都会导致您为每个实体分离导航属性,并为每个此类关系分离连接表

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

var tags = from k in context.Knights // or context.BaseEntities.OfType<Knight>()
           from t in k.Tags
           select t;
var tags=来自context.Knights//或context.BaseEntities.OfType()中的k
从t到k标签
选择t;
与标签关联的所有农民-这应该有效:

var peasants = from t in context.Tags
               from p in t.Entities.OfType<Peasant>()
               select p;
var=context.Tags中的from t
来自t.Entities.of type()中的p
选择p;

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

如果希望在
BaseEntity
中有一个列表,还必须删除子实体中的列表。您将以以下内容结束:

 List<Knight> knightsByTag = Tags.Where(t => t.GetType() == typeof (Knight)).ToList();
public abstract class BaseEntity {
    ...

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

public class Tag : BaseEntity {
    ...

    // tag subscribers
    public List<BaseEntity> Entities { get; set; }
}
公共抽象类BaseEntity{
...
//标签
公共列表标记{get;set;}
}
公共类标记:BaseEntity{
...
//标签订户
公共列表实体{get;set;}
}
如果您有任何特定的约束,在建立实体和标记之间的关系之前,您必须在应用程序中检查它们。任何其他方法都会导致您为每个实体分离导航属性,并为每个此类关系分离连接表

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

var tags = from k in context.Knights // or context.BaseEntities.OfType<Knight>()
           from t in k.Tags
           select t;
var tags=来自context.Knights//或context.BaseEntities.OfType()中的k
从t到k标签
选择t;
与标签关联的所有农民-这应该有效:

var peasants = from t in context.Tags
               from p in t.Entities.OfType<Peasant>()
               select p;
var=context.Tags中的from t
来自t.Entities.of type()中的p
选择p;

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

您能澄清并简化您的问题吗?你想问什么<代码>标记没有您定义的
骑士
。你怎么写最后一个问题?你能澄清和简化你的问题吗?你想问什么<代码>标记没有您定义的
骑士
。你怎么写最后一个查询?谢谢你的回复。我担心
包含一个派生的集合。。。
标签
(例如,T:BaseEntity中的
列表)中的通用集合是否不可行?很抱歉响应延迟。拉迪斯拉夫,你的答案并不是我想要的,但那是因为我想要的不是真正可行的。所以你的答案在技术上是正确的。谢谢你的帮助。谢谢你的回复。我担心
包含一个派生的集合。。。
标签
(例如,T:BaseEntity
中的
列表)中的通用集合是否不可行?很抱歉响应延迟。拉迪斯拉夫,你的答案并不是我想要的,但那是因为我想要的不是真正可行的。所以你的答案在技术上是正确的。谢谢你的帮助。