1

私は自分のウェブサイトのコメントシステムを作成し始めたばかりです。EFを使用していて、いくつかのテーブルをコメントテーブルにバインドしたいと思います。2つの別々のテーブルにCarエンティティとBikeエンティティがあると言えます。これら2つのテーブルのコメントのコレクションをバインドしたいと思います。

私の頭の中には、コメントテーブルに含まれる画像があります。

CommentID | EntityID | CommentText

      1        Bike_2    Hello world..

      2         Car_2         -- 

      3        Bike_3         --

私は正しいと思いますか?エンティティフレームワークでこれをどのように設定しますか?

よろしくお願いします。

4

1 に答える 1

1

(以下は、Entity Framework 4.1 から 4.3.1 および Code-First/ の場合DbContextです。)

あなたのアイデアに最も近いマッピングのタイプは、Table-per-Type (TPT) 継承マッピングです。次のようになります。

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

EntityWithCommentsCarおよび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");
    }
}

その結果、データベースには 4 つのテーブルがあります。

  • あなたのComments提案のように見えますが、およびテーブルEntityIdを直接参照しないテーブル。代わりに、基本型テーブルを参照します。CarsBicyclesEntitiesWithComments

  • 抽象基本クラスを表すテーブルEntitiesWithCommentsで、1 つの列 (列) しかありませんId

  • とin テーブルのCars間で 1 対 1 の共有主キー制約を持つテーブルIdIdEntitiesWithComments

  • とin テーブルのBicycles間で 1 対 1 の共有主キー制約を持つテーブルIdIdEntitiesWithComments

次に、たとえば、すべての青い車をロードできます。

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値は、返された行が本当に車かどうかを確認するために EF が使用する型記述子のようなものだと思いますが、よくわかりません。)

コメントを含めて 3 輪のすべての自転車をロードする場合は、次のクエリが機能します。

using (var ctx = new MyContext())
{
    var bicyclesWithThreeWheelsWithComments = ctx.EntitiesWithComments
        .Include(e => e.Comments)
        .OfType<Bicycle>()
        .Where(b => b.HasThreeWheels)
        .ToList();
}
于 2012-04-29T12:23:07.733 に答える