Entity FrameWork単一テーブル対マルチエンティティ

10937 ワード

1つのムービー情報Clipsテーブル、4つのフィールド:clipId,clipName,fileSize,fileName
 
シナリオ1:
    [Table("Clips")]

    public class Clip

    {

        public Clip()

        {

            File = new ClipFile();

        }



        [Key]

        [Column("clipId")]

        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

        public int Id { get; set; }



        [Column("clipName")]

        public string Name { get; set; }



        public ClipFile File { get; set; }

    }



    [ComplexType]

    public class ClipFile

    {

        [Column("fileSize")]

        public string Size { get; set; }



        [Column("fileName")]

        public string Name { get; set; }

    }

欠点:ClipFileがvirtualであるかどうかを明示しても、ClipFileはロードを遅らせることはありません.
シナリオ2:
 
[Table("Clips")]

    public class Clip

    {

        [Key]

        [Column("clipId")]

        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

        [ForeignKey("FileOf")]

        public int Id { get; set; }



        [Column("clipName")]

        public string Name { get; set; }



        //[Required]

        public virtual ClipFile FileOf { get; set; }

    }



    [Table("Clips")]

    public class ClipFile

    {

        [Key]

        [Column("clipId")]

        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

        [ForeignKey("ClipOf")]

        public int Id { get; set; }



        [Column("fileSize")]

        public string Size { get; set; }



        [Column("fileName")]

        public string Name { get; set; }

        

        //[Required]

        public virtual Clip ClipOf { get; set; }

    }

このシナリオにも問題があり、関連virtualエンティティクラスをIncludeで呼び出さず、常にnullであり、遅延ロードはサポートされず、憂鬱です.SqlServerは解決できると言われていますが、MySqlは解決策を見つけていません.
また,コンストラクション関数は必ずnew付属エンティティクラスに行かず,デッドサイクルに入る.
 
シナリオ3:TPH(Table per Hierarchy)の使用
public abstract class ClipBase

    {

        [Key]

        [Column("clipId")]

        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

        public int Id { get; set; }



        [Column("clipName")]

        public string Name { get; set; }

    }



    public class ClipFile : ClipBase

    {

        [Column("fileName")]

        public string FileName { get; set; }

    }



    public class ClipSize : ClipBase

    {

        [Column("fileSize")]

        public int Size { get; set; }

    }

また、Fluent APIで構成する必要があります.また、どのクラスのデータであるかを区別するために使用されるフィールドDiscriminatorをClipsに追加する必要があります.このフィールドの値は、派生クラスごとにHasValue値が異なることを保証する必要があります.
modelBuilder.Entity<ClipBase>().Map(m=>

            {

                m.ToTable("Clips");

                //m.Requires("Discriminator").HasValue("0"); // ClipBase 

            })

            .Map<ClipFile>(m => m.Requires("Discriminator").HasValue("1"))

            .Map<ClipSize>(m => m.Requires("Discriminator").HasValue("2"));

作成オブジェクトは、ベースクラスのDbSetで追加することも、派生クラス独自のDbSetで追加することもできます.選択時にベースクラスのDbSet.OfType()は、派生クラス独自のDbSetを使用することもできます.
しかし、このシナリオのマルチエンティティは、データが1つのテーブルにあるにもかかわらず、コンテンツが3つのクラスで共有されず、元の設計の初心を失った.