zoukankan      html  css  js  c++  java
  • Entity Framework 学习高级篇1—改善EF代码的方法(上)

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

    l         MergeOption.NoTracking

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

    [Test]

            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();

     

                }

            }

    l         GetObjectByKey/First

    GetObjectByKey

    在EF中,使用GetObjectByKey方法获取数据时,它首先会查询是否有缓存,如果有缓存则从缓存中返回需要的实体。如果没有则查询数据库,返回需要的实体,并添加在缓存中以便下次使用。

    First: 总从数据库中提取需要的实体。

    因此,我们应在合适的地方选择GetObjectByKey方法来获取数据,以减少对数据库的访问提升性能。示例代码如下:

    [Test]

            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而不是抛异常。示例代码如下:

    [Test]

            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);

     

                }

            }

    l         First /FirstOrDefault

    First: 当我们使用First来获取数据,如果没有符合条件的数据,那么我们的代码将会抛出异常。

    FirstOrDefault: 当我们使用FirstOrDefault来获取的数据,如果没有符合条件的数据,那么它将返回null。

    显然,对于一个良好的代码,是对可以预见的异常进行处理,而不是等它自己抛出来。示例代码如下:

    [Test]

            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);

                }

            }

    l         延迟加载/Include

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

    [Test]

            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方法,如下代码所示:

    [Test]

            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将被加载。

  • 相关阅读:
    Leetcode Binary Tree Level Order Traversal
    Leetcode Symmetric Tree
    Leetcode Same Tree
    Leetcode Unique Paths
    Leetcode Populating Next Right Pointers in Each Node
    Leetcode Maximum Depth of Binary Tree
    Leetcode Minimum Path Sum
    Leetcode Merge Two Sorted Lists
    Leetcode Climbing Stairs
    Leetcode Triangle
  • 原文地址:https://www.cnblogs.com/zwb7926/p/3277428.html
Copyright © 2011-2022 走看看