Entity Framework 学习高级篇2—改善EF代码的方法(下)

时间:2023-03-08 20:40:11

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

}

}

}

l         存储模型视图

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

为了,免去运行时生成存储模型视图,我们可以预先产生这个的存储模型视图。具体步骤如下:

首先,使用EdmGen2来产生存储模型视图,相应的命令如下:

Edmgen2 /ViewGen cs NorthwindEntites.edmx

执行此命令后,edmgen2会在当前目录下生成一个名为NorthwindEntites.GeneratedViews.cs这个文件,就是我们要使用的存储模型视图文件。

将此文件添加到项目中就行,其他的代码不需要改变,EF会自动调用此视图文件。如下示例代码:

[Test]

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.

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

l         冲突处理

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

}

上述代码片段,只是说明怎么处理并发冲突,不是具体的并发。(ps:本来是准备开个线程来模拟并发的,但是始终没成功,没明白什么原因,望高人指点呢!)