zoukankan      html  css  js  c++  java
  • 改善EF代码的方法(上)

    本节,我们将介绍一些改善EF代码的相关方法,如NoTracking,GetObjectByKey, Include等。

    > MergeOption.NoTracking

    当我们只需要读取某些数据而不需要删除、更新的时候,可以指定使用MergeOption.NoTracking的方式来执行只读查询(EF默认的方式是AppendOnly)。当指定使用NoTracking来进行只读查询时,与实体相关的引用实体不会被返回,它们会被自动设置为null。因此,使用NoTracking可以提升查询的性能。示例代码如下:

    public void NoTrackingTest()
    {
        using (var db = new NorthwindEntities1())
        {
        //针对Customers查询将使用MergeOption.NoTracking
        db.Customers.MergeOption = MergeOption.NoTracking;
        var cust = db.Customers.Where(c => c.City == "London");
        foreach (var c in cust)
            Console.WriteLine(c.CustomerID);
    
        //也可以这样写
        //var cust1 = ((ObjectQuery<Customers>)cust).Execute(MergeOption.NoTracking);
    
        //Esql写法
        //string esql = "select value c from customers as c where c.CustomerID='ALFKI'";
        //db.CreateQuery<Customers>(esql).Execute(MergeOption.NoTracking).FirstOrDefault();
    
        }
    }

    > GetObjectByKey/First

    GetObjectByKey:
    在EF中,使用GetObjectByKey方法获取数据时,它首先会查询是否有缓存,如果有缓存则从缓存中返回需要的实体。如果没有则查询数据库,返回需要的实体,并添加在缓存中以便下次使用。
    First: 总从数据库中提取需要的实体。
    因此,我们应在合适的地方选择GetObjectByKey方法来获取数据,以减少对数据库的访问提升性能。示例代码如下:

    public void GetByKeyTest()
    {
        using (var db = new NorthwindEntities1())
        {
        //从数据库中提取数据
        var cst = db.Customers.First(c => c.CustomerID == "ALFKI");
        Console.WriteLine(cst.CustomerID);
    
        //将从缓存中提取数据
        EntityKey key = new EntityKey("NorthwindEntities1.Customers", "CustomerID", "ALFKI");
        var cst1 = db.GetObjectByKey(key) as Customers;
        Console.WriteLine(cst1.CustomerID);
       }
    }

    此外,需要注意的是如果GetObjectByKey没有获取到符合条件的数据,那么它会抛异常。为了避免此情况发生,在有可能出现异常的地方,我们应该使用TryGetObjectByKey方法。TryGetObjectByKey方法获取数据的方式和GetObjectByKey类似,只是当没有取到符合条件的数据时,TryGetObjectByKey会返回null而不是抛异常。示例代码如下:

    public void TryGetByKeyTest()
    {
        using (var db = new NorthwindEntities1())
        {
        //没有符合条件的数据会有异常抛出
        EntityKey key = new EntityKey("NorthwindEntities1.Customers", "CustomerID", "风车车.Net");
        var cst = db.GetObjectByKey(key) as Customers;
        Console.WriteLine(cst.CustomerID);
    
        //没有符合条件的数据会有返回null
        EntityKey key1 = new EntityKey("NorthwindEntities1.Customers", "CustomerID", "风车车.Net");
        Object cst1 = null;
        db.TryGetObjectByKey(key1, out cst1);
        if (cst1 != null)
            Console.WriteLine(((Customers)cst1).CustomerID);
        }
    }

    > First /FirstOrDefault

    First: 当我们使用First来获取数据,如果没有符合条件的数据,那么我们的代码将会抛出异常。
    FirstOrDefault: 当我们使用FirstOrDefault来获取的数据,如果没有符合条件的数据,那么它将返回null。
    显然,对于一个良好的代码,是对可以预见的异常进行处理,而不是等它自己抛出来。示例代码如下:

    public void FirstTest()
    {
        using (var db = new NorthwindEntities1())
        {
    
        //抛异常的代码
        var cst = db.Customers.First(c => c.CustomerID == "风车车.Net");
        Console.WriteLine(cst.CustomerID);//此处将出抛异常
           
        //推荐的使用如下代码:
        var cst1 = db.Customers.FirstOrDefault(c => c.CustomerID == "风车车.Net");
        if (cst1 != null)
            Console.WriteLine(cst1.CustomerID);
        }
    }

    > 延迟加载/Include

    EF不支持实体的部分属性延迟加载,但它支持实体关系的延迟加载。默认情况,实体的关系是不会加载。如下代码:

    public void IncludeTest()
    {
        using (var db = new NorthwindEntities1())
        {
           var csts = db.Customers;
        foreach (var c in csts)
        {
            Console.WriteLine(c.CustomerID);
            foreach (var o in c.Orders)
            Console.WriteLine("   " + o.OrderID);
        }
        }
    }

    上述代码中,因为Orders没有被加载,所以在输出Orders的时候,是不会有任何输出的。
    当我们需要加载某些关联的关系时,可是用Include方法,如下代码所示:

    public void IncludeTest()
    {
        using (var db = new NorthwindEntities1())
        {
           var csts = db.Customers.Include("Orders");
        foreach (var c in csts)
        {
            Console.WriteLine(c.CustomerID);
            foreach (var o in c.Orders)
            Console.WriteLine("   " + o.OrderID);
        }
        }
    }

    上述代码中,Customers关联的Orders将被加载。

    > 根据外键得到主键的实体

    public static void WaiJianTest()
    {
        var stu = me.Student;
    
        foreach (var s in stu)
        {
        Console.WriteLine(s.StudentID);
        Console.WriteLine(s.Class.ClassName);
        Console.WriteLine("---------");
        }
    }

    其中 Class 为主键类,ClassName是主键的属性

  • 相关阅读:
    Feli的生日礼物
    session cookie
    ArcGIS FLEXnet Licensing error:96,491错误解决
    CSS块元素与内联元素(转)
    铝伯世
    netsh修改IP及DNS

    JAVA代码查错(转)
    windows7查看占用端口的进程
    php 中文字符串截取子串
  • 原文地址:https://www.cnblogs.com/xgao/p/4200604.html
Copyright © 2011-2022 走看看