Entity Framework with MySQL 学习笔记一(关系整理版)

1-1 设置

   //DataAnnotation 1-1 | 1-0 table 

    //SQLtable : member , columns : memberId, name

    //SQL basic logic : 1个table的PK, 是另一个table的PK and FK , 这就是1-1和1-0的关系

    [Table("member")]

    public class Member

    {

        [Key]

        public Int32 memberId { get; set; }

        public string name { get; set; }

        [Required]

        /*        

            1-0,这里就不要Required

            1-1关系最好是放Required啦,在insert的时候才不会出错,但是... 

            如果你写Required,那么你在做update的时候这个address不能是Null,也就是说一定要inner join出来先,不是很方便.        

        */

        public virtual Address address { get; set; }

    }

    //SQLtable : address , columns : memberId, postcode, country

    [Table("address")]

    public class Address

    {

        /*

            关键就是这个关系连接, "member" 是 tableName

        */

        [Key, ForeignKey("member")] //foreignKey 一定要写在这里,不可以写在 Member 哦

        public Int32 addressId { get; set; } //这里取名addressId也行

        public string postcode { get; set; }

        public string country { get; set; }

        public virtual Member member { get; set; }

    }

注 : ForeignKey("member") 的member 是取至于 virtual Member "member" , 这2个要一直

基本的 CRUD

using (EFDB db = new EFDB())

{

    /*insert*/

    db.members.Add(new Member

    {

        name = "keatkeat",

        address = new Address

        {

            postcode = "81300",

            country = "malaysia"

        }

    });

    db.SaveChanges();



    /*select*/

    var members = db.members.Include(m => m.address).ToList(); //要include才会一起出来哦 

         

    /*update*/

    var member = db.members.Include(m => m.address).First().name = "xinyao123";

    db.SaveChanges();



    /*delete*/

    db.members.Remove(db.members.Include(m => m.address).First()); //要include出来才能一次删除2个table的数据!

    db.SaveChanges();

}
View Code

这里有一个要注意的 : 

如果 A 和 B 是 1-1 关系, 而 B 是一抽象类 C,D 是B的派生类,那么当我们想要替换掉 C 时,我们并不能单纯的 a.b = new D() 

我们也不可以先删除再添加  

db.Bs.remove(a.b);

a.b = new D(); 

我们必须使用 transaction, SaveChanges 2 次,

transaction.open();

db.Bs.remove(a.b);

db.SaveChanges();

a.b = new D();

db.SaveChanges();

transaction.commit();

这样才可以!

 

1-n 设置

    //1-n 

    /*

        基本上如果没有必要就不要写required了,这样比较方便在update单个table的时候.(insert的时候自己要控制好!)

    */

    [Table("prod")]

    public class Prod

    {

        [Key]

        public int prodId { get; set; }

        public string code { get; set; }

        [InverseProperty("prod")] //因为有超过1个,所以我们要告诉entity,这对应哪一个

        public virtual ICollection<Color> colors { get; set; } //有多个colors,用ICollection | List 也可以

        [InverseProperty("prodx")]  

        public virtual ICollection<Color> color2s { get; set; } 

    }



    [Table("color")]

    public class Color

    {

        [Key]

        public int colorId { get; set; }

        public string name { get; set; }



        [ForeignKey("prod")] //指定一个FK, "prod" 是attr属性名,不是sql的哦

        public int prodId { get; set; }
   [ForeignKey("prodId")] //虽然写这里也是可以表达foreignKey 关系,但是最好不要这样!
public virtual Prod prod { get; set; } //有一个prod [ForeignKey("prodx")] public int prodxId { get; set; } public virtual Prod prodx { get; set; } }
InverseProperty (如果有做,lastModifier,handler就会有了),2个表有超过1个 1-n 关系,就要表明清楚对应的是哪一个。
1-n 的 foreignKey 不可以是 0, 如果真的没有也只能放 Null, 而且sql 要是nullable , foreignKey 类型是 int?.
nullable 虽然不会影响sql对foreignKey关系的验证或者级联,但是对索引搜索不好,所以还个简单的方法就是主表default create 1 row for 这种没有的情况,那么foreignKey 就可以连接到这row id 了。

 

 n-n 设置

n-n 我不鼓励用 DataAnnotation, 除非用 default的tableName,比如 category , prod  = prodcategories , columns = Prod_prodId , Category_categoryId (基本上debug几次就可以知道它的自动命名了)

如果是要自己取名字的话,比如 category_and_prod,那就麻烦多多了...

参考 : https://social.msdn.microsoft.com/Forums/en-US/9d7a4803-53c6-44be-823d-dce6e85bb497/ef-41-customize-codefirst-manytomany-table-using-attributes

    /*

       2表的连接表 

    */

    [Table("prod_mm_category")]

    public class ProdAndCategory

    {

       

        [Key]

        public Int32 ProdAndCategoryId { get; set; }

        [Key]

        [Column(Order = 1)]

        [ForeignKey("category")]

        public int categoryId { get; set; }

        [Key]

        [Column(Order = 2)]

        [ForeignKey("prod")]

        public int prodId { get; set; }

        public Category category { get; set; }

        public Prod prod { get; set; }

    }

    [Table("category")]

    public class Category

    {

        [Key]

        public Int32 categoryId { get; set; }

        public string name { get; set; }

        /*

            注意这里是 ProdAndCategory 哦

        */

        public virtual ICollection<ProdAndCategory> prods { get; set; } 

    }

    [Table("prod")]

    public class Prod

    {

        [Key]

        public Int32 prodId { get; set; }

        public string code { get; set; }

        public virtual ICollection<ProdAndCategory> categorys { get; set; }

    }
View Code

insert 也超麻烦..

db.categorys.Add(new Category

{

    name = "Man",

    prods = new List<ProdAndCategory> 

    {

        /*

            这里很麻烦吧... 

        */

            new ProdAndCategory 

            {

                prod = new Prod 

                {

                code = "MK100",

                }

            },

            new ProdAndCategory 

            {

                prod = new Prod 

                {

                code = "MK200",

                }

            },

    }

});
View Code

所以可以考虑用 Fluent API 替代

protected override void OnModelCreating(DbModelBuilder modelBuilder)

{

    /*

        cateogry "HasMany" prod , prod "WithMany" category , mapping logic            

    */

    modelBuilder.Entity<Category>().HasMany<Prod>(c => c.prods).WithMany(p => p.categorys).Map(m =>

    {

        m.MapLeftKey("Category_categoryId"); //第3 table 的连接 columnName 可以自己顺便取

        m.MapRightKey("prodId"); //第3 table 的连接 columnName 

        m.ToTable("prodcategories"); //第3 tableName

    });

    base.OnModelCreating(modelBuilder);         

}

用 Fluent API 或是自动命名 insert 也简单了 

db.categorys.Add(new Category

{

    name = "Man",

    prods = new List<Prod> 

    {

        new Prod 

        {

            code = "MK100",

        },

        new Prod 

        {

            code = "MK200",

        } 

    }

});

db.SaveChanges();
View Code

 

你可能感兴趣的:(framework)