我刚开始为我的网站创建评论系统。我正在使用EF,我想将一些表绑定到Comments表。我们可以说我在两个单独的表中有一个Car实体和一个Bike实体,我想绑定这两个表的注释集合。
在我看来,我有一张评论表中包含的图片:
CommentID | EntityID | CommentText
1 Bike_2 Hello world..
2 Car_2 --
3 Bike_3 --
我在想什么?如何使用实体框架进行设置?
最好的问候。
答案 0 :(得分:1)
(以下内容适用于实体框架4.1至4.3.1和代码优先/ DbContext
。)
与您的想法最接近的映射类型是Table-per-Type (TPT) inheritance mapping。它看起来像这样:
public abstract class EntityWithComments
{
public int Id { get; set; }
public ICollection<Comment> Comments { get; set; }
}
public class Comment
{
public int Id { get; set; }
public string CommentText { get; set; }
public int EntityId { get; set; }
public EntityWithComments Entity { get; set; }
}
public class Car : EntityWithComments
{
public string Manufacturer { get; set; }
public string Color { get; set; }
}
public class Bicycle : EntityWithComments
{
public int Weight { get; set; }
public bool HasThreeWheels { get; set; }
}
EntityWithComments
是Car
和Bicycle
以及其他实体的基类。然后你有一个派生的DbContext
类:
public class MyContext : DbContext
{
public DbSet<EntityWithComments> EntitiesWithComments { get; set; }
public DbSet<Comment> Comments { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
.ToTable("Cars");
modelBuilder.Entity<Bicycle>()
.ToTable("Bicycles");
}
}
因此,您在数据库中有四个表:
Comments
表看起来像您的提案,但EntityId
不会直接引用Cars
和Bicycles
表。相反,它引用基本类型表EntitiesWithComments
。
表示抽象基类的表EntitiesWithComments
,只有一列,即Id
列。
表格Cars
,Id
与表Id
中的EntitiesWithComments
之间存在一对一的共享主键约束
表格Bicycles
,Id
与表Id
中的EntitiesWithComments
之间存在一对一的共享主键约束
然后你可以 - 例如 - 加载所有蓝色汽车:
using (var ctx = new MyContext())
{
var blueCars = ctx.EntitiesWithComments.OfType<Car>()
.Where(c => c.Color == "Blue")
.ToList();
}
由于EntitiesWithComments
基表不包含除Id
之外的任何列,因此表之间不存在必要的连接。生成的SQL看起来像这样,只触及派生类型的表:
SELECT
'0X0X' AS [C1],
[Extent1].[Id] AS [Id],
[Extent1].[Manufacturer] AS [Manufacturer],
[Extent1].[Color] AS [Color]
FROM [dbo].[Cars] AS [Extent1]
WHERE N'Blue' = [Extent1].[Color]
(我想,这个查询中的奇怪0X0X
值是一种类型描述符,用于检查返回的行是否真的是汽车,但我不确定。)
如果您想加载所有带三个轮子的自行车,包括他们的评论,以下查询有效:
using (var ctx = new MyContext())
{
var bicyclesWithThreeWheelsWithComments = ctx.EntitiesWithComments
.Include(e => e.Comments)
.OfType<Bicycle>()
.Where(b => b.HasThreeWheels)
.ToList();
}