EF
团队
推出了一套比较完整的缓存和
SQL
执行日志的解决方案,
EFProviderWrappers
。他们的做法是在原来的EF Provider之上,再加一层包装,通过这层包装拦截,进行
数据
缓存和日志监控。数据缓存功能与NHibernate的二级缓存相比,优势在于简单轻量。
最近在做的一个项目采用了EntityFramework4.3 Code First 模式开发,希望引入这个组件完成日志跟踪和缓存功能。
在网上搜寻EFProviderWrappers 相关资料基本上都是基于ObjectContext而不是DbContext。而且这个组件也没有更新,最新版本也是2011年4月。
有什么方法才能在EF4上正常使用呢?
现将研究的方法总结一下
- 首先是下载这套组件EFProviderWrapperToolKit
- 在项目中引用EFProviderWrapperToolkit.dll、EFTracingProvider.dll和 EFCachingProvider.dll
- 在Web.Config 或App.Config配置文件中增加配置节
<connectionStrings>
<add name="TestContext"
providerName="System.Data.SqlClient"
connectionString="Server=Wyd\Instance;Initial Catalog=DatabaseName;User ID=sa;Password=123;MultipleActiveResultSets=True"/>
</connectionStrings>
<system.data>
<DbProviderFactories>
<add name="EF Caching Data Provider"
invariant="EFCachingProvider"
description="Caching Provider Wrapper" type="EFCachingProvider.EFCachingProviderFactory, EFCachingProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b"/>
<add name="EF Tracing Data Provider"
invariant="EFTracingProvider"
description="Tracing Provider Wrapper" type="EFTracingProvider.EFTracingProviderFactory, EFTracingProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b"/>
<add name="EF Generic Provider Wrapper"
invariant="EFProviderWrapper"
description="Generic Provider Wrapper" type="EFProviderWrapperToolkit.EFProviderWrapperFactory, EFProviderWrapperToolkit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b"/>
</DbProviderFactories>
</system.data>
4.在DbContext类中 建立两个构造方法(这就是关键处了)
1
public
class TestContext : DbContext
2 {
3
public TestContext()
4 {
5 }
6
public TestContext(DbConnection conn)
7 :Base(conn,True)
8 {
9 }
10 }
5. OverLoad the DbConnection.
1
using (
var context =
new TextContext(CreateConnectionWrapper(
@"
name=TestContext
")))
2 {
3
var product = context.ProductCollection.Find(
1);
4 }
6. 添加CreateConnectionWrapper 方法
private
static DbConnection CreateConnectionWrapper(
string nameOrConnectionString)
{
var providerInvariantName =
"
System.Data.SqlClient
";
var connectionString = nameOrConnectionString;
//
name=connectionName format
var index = nameOrConnectionString.IndexOf(
'
=
');
if (nameOrConnectionString.Substring(
0,index).Trim().Equals(
"
name
", StringComparison.OrdinalIgnoreCase))
{
nameOrConnectionString=nameOrConnectionString.Substring(index +
1).Trim();
}
//
look up connection string name
var connectionStringSetting = ConfigurationManager.ConnectionStrings[nameOrConnectionString];
if (connectionStringSetting !=
null)
{
providerInvariantName = connectionStringSetting.ProviderName;
connectionString = connectionStringSetting.ConnectionString;
}
//
create the special connection string with the provider name in it
var wrappedConnectionString = wrappedProvider=
"
+ providerInvariantName +
";
"
+ connectionString;
//
create the tracing wrapper
var connection =
new EFTracingConnection
{
ConnectionString = wrappedConnectionString };
//
写日志logging
connection.CommandFinished += (sender, args) => Console.WriteLine(args.ToTraceString());
return connection;
}