• 改善EF代码的方法(下)


    本节,我们将介绍一些改善EF代码的方法,包括编译查询、存储模型视图以及冲突处理等内容。

    > CompiledQuery

    提供对查询的编译和缓存以供重新使用。当相同的查询需要执行很多遍的时候,那么我们可以使用ComplieQuery将查询的语句进行编译以便下次使用,这样可以免去对同一语句的多次处理,从而改善性能。
    示例代码如下:

    public void ComplieTest()
    {
        using (var db = new NorthwindEntities1())
        {
        //对查询进行编译
        var customer = CompiledQuery.Compile<NorthwindEntities1, IQueryable<Customers>>(
            (database) => database.Customers.Where(c => c.City == "London"));
           
        //执行20次相同的查询
        for (int i = 0; i < 20; i++)
        {
            DateTime dt = System.DateTime.Now;
            foreach (var c in customer(db))
            Console.WriteLine(c.CustomerID);
            Console.WriteLine(DateTime.Now.Subtract(dt).TotalMilliseconds);
            Console.WriteLine("---------------------------------------------------");
        }
    
         }
    }

    > 存储模型视图

    在EF中,当执行实体查询的时候,运行时首先将实体模型转换成ESQL视图,而ESQL视图则是根据msl文件来生成相应的代码。此外,ESQL视图包含了相应的查询语句。ESQL视图被创建后将在应用程序域中进行缓存以便下次使用。这个运行时生成存储模型视图是比较耗时的过程。
    为了,免去运行时生成存储模型视图,我们可以预先产生这个的存储模型视图。具体步骤如下:
    首先,使用EdmGen2来产生存储模型视图,相应的命令如下:

      Edmgen2 /ViewGen cs NorthwindEntites.edmx

    执行此命令后,edmgen2会在当前目录下生成一个名为NorthwindEntites.GeneratedViews.cs这个文件,就是我们要使用的存储模型视图文件。
    将此文件添加到项目中就行,其他的代码不需要改变,EF会自动调用此视图文件。
    如下示例代码:

    public void ViewTest()
    {
        using (var db = new NorthwindEntities1())
        {
        var suppliers = db.Suppliers;
        foreach (var s in suppliers)
            Console.WriteLine(s.ContactName);
        }
    }

    没有使用存储模型视图的情况是:
    1 passed, 0 failed, 0 skipped, took 7.09 seconds.

    项目中添加了NorthwindEntites.GeneratedViews.cs文件,执行情况是:
    1 passed, 0 failed, 0 skipped, took 5.38 seconds.

    可见,使用了存储模型视图的确是提高了性能。

    > 冲突处理

    在EF中,默认情况并不会检查并发冲突。因为EF实现的是乐观的并发模式,当有并发的冲突发生时,将会抛出Optimistic Concurrency Exception异常。我们可以通过使用RefreshMode这个枚举来指定当发生冲突时如何处理。

    RefreshMode有两中枚举值:
    ClientsWins: 当提交修改,更新数据库中的值
    StoreWins: 放弃修改,使用数据库中的值

    示例代码片段如下:

      var db2 = new NorthwindEntities1();
        var customer2 = db2.Customers.FirstOrDefault(c => c.CustomerID == "2009");
        if (customer2 != null)
        {
        customer2.ContactName = "风车车.Net";
        customer2.City = "CD";
        customer2.Region = "GX";
        }
        try
        {
        db2.SaveChanges();
        }
        catch (OptimisticConcurrencyException ex) //捕获到冲突,则进行相应的处理
        {
        db2.Refresh(RefreshMode.ClientWins, customer2);
        db2.SaveChanges();
        }

    上述代码片段,只是说明怎么处理并发冲突,不是具体的并发。

  • 相关阅读:
    git
    Flask 上传文件 IO错误
    对0位压缩的 ipv6,进行补全
    字符编码
    struct 模块,pack 和 unpack,用法详细说明
    MySQLdb 操作数据库
    字节Byte 与 位bit 的关系
    vim
    python 内置函数 char
    time,datetime 模块
  • 原文地址:https://www.cnblogs.com/xgao/p/4200608.html
Copyright © 2020-2023  润新知