需要在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; }
}
(是的,我知道King,Knight和Peasant在这里是一样的。但正如信使在Monty Python和圣杯中所说:“它只是一个模特。”)
所以无论如何,这个模型很好用,但我更喜欢T通用列表,而不是特定的演员。数据库中的表越少,从标签查询实体时的开销就越小。如何转换所有List&lt; Entity&gt; Tag中的属性为单个通用List&lt; T&gt;其中T:BaseEntity,这会导致我可以查询特定衍生物的单个查找表吗?类似的东西:
List<Knight> knightsByTag = Tags.Where(t => t.GetType() == typeof (Knight)).ToList();
编辑: Yeesh。对不起,有一些实际的代码仍在那里。
@DarthVader:
答案 0 :(得分: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;
请注意,映射继承会对查询性能产生负面影响。