zoukankan      html  css  js  c++  java
  • Model First 开发方式

    概述

       在项目一开始,没有数据库时,可以借助 EF 设计模型,然后根据模型同步完成数据库中表的创建,这就是 Model First 开发方式。

       总结一点就是:现有模型再有表。

    创建 Model First Demo

      创建 Model First 的步骤如下:

      (1)创建控制台项目

         右击解决方案 “EFDemo”,选择 “添加项目 → 控制台应用程序”,并将项目命名为 ModelFirst。

      (2)添加 ADO.NET 实体模型

         右击 ModelFirst 项目,再选择 “添加新建项 → ADO.NET 实体数据模型” 并命名为 ModelFirstModel.edmx,创建空模型后单击 “完成”。

      (3)添加实体 Customer

         ① 添加实体和几个必要的测试字段。切记,一定要添加主键。主键既可以是自增长的数字类型,也可以是 Guid 类型。

            右击空白处 → 新增 → 实体。

            实体名称(Customer),实体集(Customer),确定。

         ② 添加标量属性。

            标量属性可以看成数据库中的普通字段(主键和外键之外的)。

            我们在设计字段属性的时候,一定要记得设置其最大范围,否则最终会生成一个比较大的默认范围,严重影响性能,并占用不必要的磁盘空间。

            右击实体 → 新增 → 标量属性。

            注意:“名称”、“可以为 Null”、“类型”、“最大长度”。

         ID 属性:ID 是实体键(主键,类型为 Int32,实体键设为True),存储方式是自增长(Identity)。  (属性 “实体键”,表示设置主键)

         (String 可以选择是否采用 Unicode 编码,如果采用就对应 SQL Server 中的 nvarchar 类型)

         (Decimal 表示指定小数位数及数据精度的类型,范围表示小数个数,精度显示总的数据位数)

      (4)添加实体之间的联系

         再添加一个实体 Product:右击空白处 → 新增 → 实体,属性类型设为 Guid。

         自增长主键和 Guid 主键的比较:

           Guid 比自增长要快,因为自增长会先查询表中最大的 ID,然后锁表,再在这个最大的 ID 基础上加 1,然后插入数据表。

           自增长也有自己的长处,比如占用空间小,因为它是 int 类型的,而 Guid 一般是 32 或 64 个字符长度。还有就是比较清晰,不像 Guid 那么大。如果涉及数据迁移,自增长主键就会变得非常不方便,而 Guid 的优势则非常明显。

         再依次添加标量属性 Name、Price、Weight。

         然后添加实体 Order 以及标量属性 OrderNO、Amount、CreateTime。

         接着,我们添加两个实体之间的关联,右击工作面板空白处 → 新增 → 关联,在 “添加关联” 对话框中进行设置。(设置实体表以及多重性关系,同时保证两个都勾选导航属性)

           Customer 实体和 Order 实体上面的导航属性不要去掉,因为后面用它来查询将会变得非常方便。

           导航属性,顾名思义,就是根据这个属性可以找到一个和它关联的对象实体。

         然后,我们再添加 Customer 和 Product 多对多的关联。

         关于 “关联”  的说明如下:

           1:1,性能低(不会延迟加载,添加时必须同时创建两个对象),尽量不要使用,可以自己实现逻辑代码完成这种操作。(查看一下表结构,可以发现本质还是 1:m 的结构)

           1:m

           M:n:可以手动创建中间表采用 1:m 关系,也可以直接使用此种关系,EF 会自动创建中间表。

           在创建关联时,可以选择是否要创建导航属性、外键。

         添加完成之后,按 Ctrl + S 组合键,会在 ModelFirstModel.edmx 中 ModelFirstModel.tt 下面生成 Customer、Order 和 Product 三个类。(.tt 后缀的文件为 T4 模板,会面会单独讲解)(如果没有还是可以继续执行的)

      (5)根据模型创建数据库

         右击工作区空白处,根据模型生成数据库,将数据库命名为 ModelFirstDB,并执行 SQL 脚本创建数据库。

         单击 “根据模型生成数据库” 操作后选择数据源、填写服务器名、选择或输入数据库名称(如果没有将会提示新建),单击 “确定” 按钮。

         单击 “下一步 → 完成”,生成 DLL脚本,然后执行生成的 DLL 脚本。(执行 DLL 脚本完成后,我们会看到数据库中出现了 4 张表,其中 CustomerProduct 表是 EF 为了实现多对多关系而自动创建的)

      (6)导航属性的应用

        ① 创建测试数据。

          要先添加 Customer 实体的数据,因为 Order 实体和 Product 实体都引用了 Customer 实体。

            static void AddTestData()
            {
                using (ModelFirstModelContainer db = new ModelFirstModelContainer())
                {
                    Customer cus = new Customer
                    {
                        Name = "楚留香",
                        Age = 27,
                        CompanyName = "大旗门",
                        Telphone = "15243641131"
                    };
    
                    Order order1 = new Order
                    {
                        Amount = 15,
                        CreateTime = DateTime.Now,
                        OrderNO = "2016043001",
                        CustomerId = cus.Id
                    };
    
                    Order order2 = new Order
                    {
                        Amount = 16,
                        CreateTime = DateTime.Now,
                        OrderNO = "2016043002",
                        Customer = cus
                    };
    
                    Product prod = new Product
                    {
                        ID = Guid.NewGuid(),
                        Name = "牛栏1段",
                        Price = 12,
                        Weight = 80,
                        Customer = new List<Customer>() { cus }
                    };
    
                    db.Customer.Add(cus);
                    db.Product.Add(prod);
                    db.Order.Add(order1);
                    db.Order.Add(order2);
    
                    if(db.SaveChanges() > 0)    //db.SaveChanges()默认是已经开启了事务的,而且在这之前都只进行了一次数据库的连接,这种类似于批处理的操作大大地提升了性能。
                    {
                        Console.WriteLine("添加成功!");
                    }
                    else
                    {
                        Console.WriteLine("添加失败!");
                    }
                }
            }

        注意:db.SaveChanges() 默认是已经开启了事务的,而且在这之前都只进行了一次数据库的连接,这种类似于批处理的操作大大地提升了性能。

      ② 查询客户楚留香的所有订单信息:

            static void SearchCusOrder()
            {
                using (ModelFirstModelContainer db = new ModelFirstModelContainer())
                {
                    var orderList = from o in db.Order where o.Customer.Name == "楚留香" select o;
                    Console.WriteLine("客户楚留香的所有订单如下:");
    
                    orderList.ToList().ForEach(o => Console.WriteLine(string.Format("订单号:{0},订单金额:{1},订单创建时间:{2}", o.OrderNO, o.Amount, o.CreateTime)));
                    Console.ReadKey();
                }
            }

        这里先查 Order 表信息,然后直接通过导航属性 Customer 来过滤信息。

        当然,我们也可以通过使用 Join 来查询,达到同样的查询效果。

                    var orderList = from c in db.Customer join o in db.Order on c.Id equals o.CustomerId where c.Name == "楚留香" select o;

        那么,什么时候使用 join 查询,什么时候使用导航属性查询呢?

        导航属性就相当于 SQL 中的子查询。Join 查询和 SQL 中的 Inner Join 查询一样,所以当两张表的数据量都大的时候就使用导航属性查询,在数据量不大的情况下使用 join 查询

  • 相关阅读:
    Combine 框架,从0到1 —— 4.在 Combine 中使用计时器
    Combine 框架,从0到1 —— 4.在 Combine 中使用通知
    Combine 框架,从0到1 —— 3.使用 Subscriber 控制发布速度
    Combine 框架,从0到1 —— 2.通过 ConnectablePublisher 控制何时发布
    使用 Swift Package Manager 集成依赖库
    iOS 高效灵活地配置可复用视图组件的主题
    构建个人博客网站(基于Python Flask)
    Swift dynamic关键字
    Swift @objcMembers
    仅用递归函数操作逆序一个栈(Swift 4)
  • 原文地址:https://www.cnblogs.com/zhangchaoran/p/8888946.html
Copyright © 2011-2022 走看看