EntityFramework的CodeFirst项目,实现主从表的增删改查

文章目录

  • 主体
    • 建立新项目
    • 建立POCO 类
    • 添加新项->数据->ADO.NET数据实体->空CODE FIRST模型
    • mydb.cs中添加dbset:
    • 新建保存数据
    • 删除数据
    • 级联查询
  • EF的三种加载数据方式
    • (一)延迟加载(默认):
    • (二)贪婪加载:
    • (三)显示加载:
  • 参考链接
  • 其它
      • 设置初始化数据

主体

建立新项目

建立POCO 类

订单及订单项

public class Morder
   {
       public int ID { get; set; }
       [Display(Name = "订单号")]
       [Required]
       public string orderNumber { get; set; }
       public ICollection<MorderDetail> orderDetails { get; set; }
   }
   public class MorderDetail
   {
       public int ID { get; set; }
       [Display(Name = "订单条目")]
       [Required]
       public string itemName { get; set; }

       //下面两个建立关联,对应订单
       public int MorderID { get; set; }
       public virtual Morder order { get; set; }

   }

添加新项->数据->ADO.NET数据实体->空CODE FIRST模型

mydb.cs中添加dbset:

  public virtual DbSet<Morder> orders{ get; set; }
  public virtual DbSet<MorderDetail> orderDetails { get; set; }

新建保存数据

using(var db=new mydb())
{
 	//主表
   Morder od = new Morder();
   od.orderNumber = "010025";
   od.orderDetails = new List<MorderDetail>();
   //从表
   MorderDetail odd = new MorderDetail();
   odd.itemName = "苹果";
   od.orderDetails.Add(odd);
   db.orders.Add(od);
   //保存
   db.SaveChanges();
}

删除数据

 using (var db = new mydb())
 {
     var todel = db.orders.Where(p => p.orderNumber == "010025");
     db.orders.RemoveRange(todel);
     db.SaveChanges();
 }

== 此处删除是级联删除,在删除主表数据时,自动删除从表数据。如果想禁用级联删除或允许部分级联删除,可以在mydb.cs中添加重写的OnModelCreating方法 ==

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // 禁用一对多级联删除
    modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
   //但仍然可以指定某个表格可以级联删除 
   modelBuilder.Entity<MorderDetail>()
   .HasRequired(t => t.order)
   .WithMany(t => t.orderDetails)
   .HasForeignKey(d => d.MorderID)
   .WillCascadeOnDelete(false);
   //上面的语句意思是:子表模型类MorderDetail
   //.需要自己类定义中中有指向主表的属性order
   //.order一对多到order.orderDetails属性指向的子表
   //.通过子表外键MorderID
   //可以级联删除
   //上面四个括号内分别填:子表模型类名,子表模型中指向父表的属性名,父表模型中指向子表的属性,子表模型指向父表的id属性
}

级联查询

var l=db.orders.ToList();

上面代码可以加载主表数据。但每一个的orderDetails=null

var l=db.orders.Include(p=>p.orderDetails).ToList();

上面代码可以显式加载从表数据

EF的三种加载数据方式

EF的关联实体加载有三种方式:Lazy Loading,Eager Loading,Explicit Loading,其中Lazy Loading和Explicit Loading都是延迟加载。

(一)延迟加载(默认):

Lazy Loading使用的是动态代理,默认情况下,如果POCO类满足以下两个条件,EF就使用Lazy Loading:

  1. POCO类是Public且不为Sealed。
  2. 导航属性标记为Virtual。
    关闭Lazy Loading,可以将LazyLoadingEnabled设为false,如果导航属性没有标记为virtual,Lazy Loading也是不起作用的。

(二)贪婪加载:

不设置导航属性为virtual,并且对导航属性使用Include,Eager Loading使用Include方法关联预先加载的实体。

(三)显示加载:

不设置导航属性为virtual,并且对导航属性使用Reference(单个对象).Load()或Collection(对象集).Load()。Explicit Loading使用Entry方法,对于集合使用Collection,单个实体则使用Reference。

var cls = query.Single();
db.Entry(cls).Collection(v => v.Student).Load();//加载集合使用Collection方法
var student = db.Student.First();
db.Entry(student).Reference(v => v.Classes).Load();//加载单个实体使用Reference方法

参考链接

参见导航属性的加载

其它

设置初始化数据

建立初始化类

class DBinitializer : DropCreateDatabaseAlways<MyModel>
    {
        protected override void Seed(MyModel context)
        {
            base.Seed(context);
            var c = new MODEL.Company();
            c.CompanyName = "a";
            c.ContactMan = "b";
            context.Companys.Add(c);
            context.SaveChanges();
        }
}

//在mymodel.cs(dbcontext类)中添加初始化语句:
  public MyModel()  : base("name=MyModel")
        {
            Database.SetInitializer(new DBinitializer());
        }

迁移:
迁移是指,在开发完成以后,用户使用过程中会增加数据,后来提出需求,更改了模型,需要将原有数据迁移动新数据库并修改表格结构。
所在交付用户使用前,就要进行一次迁移准备工作,将当前的数据库表状态记录下来,以后在迁移时自动对比模型更改并产生迁移脚本,以实现最大限度的用户数据保留。

在NUGET包控制台中运行命令:
Enable-Migrations -EnableAutomaticMigrations
执行成功后,Portal控制台应用程序代码结构中,添加Migrations文件夹,并生成类文件Configuration.cs。
然后在控制台下利用Add-Migration 与Update-Database 命令更新数据的变更,生产的SQL文件可以进行修改,以保留数据,具体用法请百度

你可能感兴趣的:(C#代码,EF)