对我在EF的实体的盲评

时间:2012-04-28 13:33:02

标签: asp.net-mvc entity-framework

我刚开始为我的网站创建评论系统。我正在使用EF,我想将一些表绑定到Comments表。我们可以说我在两个单独的表中有一个Car实体和一个Bike实体,我想绑定这两个表的注释集合。

在我看来,我有一张评论表中包含的图片:

CommentID | EntityID | CommentText

      1        Bike_2    Hello world..

      2         Car_2         -- 

      3        Bike_3         --

我在想什么?如何使用实体框架进行设置?

最好的问候。

1 个答案:

答案 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; }
}

EntityWithCommentsCarBicycle以及其他实体的基类。然后你有一个派生的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不会直接引用CarsBicycles表。相反,它引用基本类型表EntitiesWithComments

  • 表示抽象基类的表EntitiesWithComments,只有一列,即Id列。

  • 表格CarsId与表Id中的EntitiesWithComments之间存在一对一的共享主键约束

    < / LI>
  • 表格BicyclesId与表Id中的EntitiesWithComments之间存在一对一的共享主键约束

    < / LI>

然后你可以 - 例如 - 加载所有蓝色汽车:

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();
}