C# enterprise library 5.0是否缓存datareader和访问器方法的自定义类之间的映射
想知道Enterprise Library 5.0的访问器方法是否缓存datareader的字段以及自定义类以提高性能,从而在将datareader映射到对象时不会使用反射查找自定义类上的字段名,也不会查找datareader上的字段名?因为对于每个访问/代码块,将自定义类字段映射到datareader字段是一项非常昂贵的操作C# enterprise library 5.0是否缓存datareader和访问器方法的自定义类之间的映射,c#,.net,performance,enterprise-library,enterprise-library-5,C#,.net,Performance,Enterprise Library,Enterprise Library 5,想知道Enterprise Library 5.0的访问器方法是否缓存datareader的字段以及自定义类以提高性能,从而在将datareader映射到对象时不会使用反射查找自定义类上的字段名,也不会查找datareader上的字段名?因为对于每个访问/代码块,将自定义类字段映射到datareader字段是一项非常昂贵的操作 public partial class _Default : System.Web.UI.Page { protected void Page_Load(obj
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Database db = EnterpriseLibraryContainer.Current.GetInstance<Database>();
var r = db.ExecuteSqlStringAccessor<Region>("SELECT * FROM Region");
}
}
public class Region
{
public string RegionnId { get; set; }
public string Name { get; set; }
}
public分部类\u默认值:System.Web.UI.Page
{
受保护的无效页面加载(对象发送方、事件参数e)
{
数据库db=EnterpriseLibraryContainer.Current.GetInstance();
var r=db.ExecuteSqlStringAccessor(“选择*来自区域”);
}
}
公共类区域
{
公共字符串RegionnId{get;set;}
公共字符串名称{get;set;}
}
从,该方法通过:
public static IEnumerable<TResult> ExecuteSqlStringAccessor<TResult>(this Database database, string sqlString)
where TResult : new()
{
return CreateSqlStringAccessor<TResult>(database, sqlString).Execute();
}
即:
public static IMapBuilderContext<TResult> MapAllProperties()
{
IMapBuilderContext<TResult> context = new MapBuilderContext();
var properties =
from property in typeof(TResult).GetProperties(BindingFlags.Instance | BindingFlags.Public)
where IsAutoMappableProperty(property)
select property;
foreach (var property in properties)
{
context = context.MapByName(property);
}
return context;
}
publicstaticimapbuildercontext MapAllProperties()
{
IMapBuilderContext上下文=新建MapBuilderContext();
var特性=
来自typeof(TResult).GetProperties(BindingFlags.Instance | BindingFlags.Public)中的属性
其中为自动映射属性(属性)
选择属性;
foreach(属性中的var属性)
{
context=context.MapByName(属性);
}
返回上下文;
}
所以没有;我看不到任何缓存的迹象。您可以添加一些,或者您可以使用domething,它已经实现了物化器和参数化缓存(*cough*dapper dot net*cough*)以下是entlib支持团队建议的一个简单而好的破解方法(您可以在以下位置查看完整线程): randylevy Mon晚上11:39不,没有任何缓存 划船制图器。我所知道的唯一用于数据访问的缓存 应用程序块是存储过程参数缓存 如果使用默认映射器,则可以缓存结果 并传递到ExecuteSqlStringAccessor方法,因为它 支持IRowMapper和IResultSetMapper重载 例如:
公共类RowMapperCache
{
私有字典缓存=新字典();
私有对象锁定器=新对象();
公共IRowMapper GetCachedMapper(),其中T:new()
{
类型=类型(T);
锁(储物柜)
{
如果(!包含(类型))
{
cache[type]=MapBuilder.BuildAllProperties();
}
}
将cache[type]作为IRowMapper返回;
}
私有布尔包含(T型)
{
返回cache.ContainsKey(类型);
}
}
//检索默认映射器并缓存它
IRowMapper regionMapper=rowMapperCache.GetCachedMapper();
var db=EnterpriseLibraryContainer.Current.GetInstance();
var r=db.ExecuteSqlStringAccessor(“选择*自区域”,regionMapper);
再次从EntLib更新(更好的解决方案):
谢谢。也许,可以将其放在Enterprise Library 6的桌面上
既然这似乎是个好主意
为了好玩,我对示例进行了一些改进,以存储RowMapperCache
作为EnterpriseLibraryContainer中的一个单件,以便
可以像其他企业库对象一样检索。虽然
不是企业库“本机”类,而是使用RowMapperCache
只有使用企业库,所以存储它不是一个巨大的飞跃
容器(特别是如果您没有使用完整的Unity IoC)
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
使用Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ContainerModel;
使用Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ContainerModel.Unity;
使用Microsoft.Practices.EnterpriseLibrary.Data;
使用Microsoft.Practices.ServiceLocation;
使用Microsoft.Practices.Unity;
命名空间RowMapperConsole
{
公共类区域{}
公共类RowMapperCache
{
私有字典缓存=新字典();
私有对象锁定器=新对象();
公共IRowMapper GetCachedMapper(),其中T:new()
{
类型=类型(T);
锁(储物柜)
{
如果(!包含(类型))
{
cache[type]=MapBuilder.BuildAllProperties();
}
}
将cache[type]作为IRowMapper返回;
}
私有布尔包含(T型)
{
返回cache.ContainsKey(类型);
}
}
班级计划
{
静态void Main(字符串[]参数)
{
应用程序初始化();
// ...
IEnumerable regions=GetRegions();
}
公共静态无效应用程序初始化()
{
配置容器(容器=>
{
//登记为单身人士
RegisterType(新的ContainerControlledLifetimeManager());
});
}
公共静态无效配置容器(操作)
{
IUnityContainer容器=新的UnityContainer();
如果(操作!=null)
行动(集装箱);
IContainerConfigurator configurator=新的UnityContainerConfigurator(容器);
EnterpriseLibraryContainer.ConfigureContainer(configurator,ConfigurationSourceFactory.Create());
IServiceLocator=新的UnityServiceLocator(容器);
EnterpriseLibraryContainer.Current=定位器;
}
公共静态IEnumerable GetRegions()
{
IRowMapper regionMapper=EnterpriseLibraryContainer.Current.GetInstance()
.GetCachedMapper();
var db=EnterpriseLibraryContainer.Current.GetInstance();
返回db.ExecuteSqlStringAccessor(“选择*来自区域”,reg
return MapAllProperties().Build();
public static IMapBuilderContext<TResult> MapAllProperties()
{
IMapBuilderContext<TResult> context = new MapBuilderContext();
var properties =
from property in typeof(TResult).GetProperties(BindingFlags.Instance | BindingFlags.Public)
where IsAutoMappableProperty(property)
select property;
foreach (var property in properties)
{
context = context.MapByName(property);
}
return context;
}
public class RowMapperCache
{
private Dictionary<Type, object> cache = new Dictionary<Type, object>();
private object locker = new object();
public IRowMapper<T> GetCachedMapper<T>() where T : new()
{
Type type = typeof(T);
lock (locker)
{
if (!Contains(type))
{
cache[type] = MapBuilder<T>.BuildAllProperties();
}
}
return cache[type] as IRowMapper<T>;
}
private bool Contains(T type)
{
return cache.ContainsKey(type);
}
}
// retrieve default mapper and cache it
IRowMapper<Region> regionMapper = rowMapperCache.GetCachedMapper<Region>();
var db = EnterpriseLibraryContainer.Current.GetInstance<Database>();
var r = db.ExecuteSqlStringAccessor<Region>("SELECT * FROM Region", regionMapper);
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ContainerModel;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ContainerModel.Unity;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.ServiceLocation;
using Microsoft.Practices.Unity;
namespace RowMapperConsole
{
public class Region {}
public class RowMapperCache
{
private Dictionary<Type, object> cache = new Dictionary<Type, object>();
private object locker = new object();
public IRowMapper<T> GetCachedMapper<T>() where T : new()
{
Type type = typeof(T);
lock (locker)
{
if (!Contains(type))
{
cache[type] = MapBuilder<T>.BuildAllProperties();
}
}
return cache[type] as IRowMapper<T>;
}
private bool Contains(T type)
{
return cache.ContainsKey(type);
}
}
class Program
{
static void Main(string[] args)
{
ApplicationInitialize();
// ...
IEnumerable<Region> regions = GetRegions();
}
public static void ApplicationInitialize()
{
ConfigureContainer(container =>
{
// Register as Singleton
container.RegisterType<RowMapperCache>(new ContainerControlledLifetimeManager());
});
}
public static void ConfigureContainer(Action<IUnityContainer> action)
{
IUnityContainer container = new UnityContainer();
if (action != null)
action(container);
IContainerConfigurator configurator = new UnityContainerConfigurator(container);
EnterpriseLibraryContainer.ConfigureContainer(configurator, ConfigurationSourceFactory.Create());
IServiceLocator locator = new UnityServiceLocator(container);
EnterpriseLibraryContainer.Current = locator;
}
public static IEnumerable<Region> GetRegions()
{
IRowMapper<Region> regionMapper = EnterpriseLibraryContainer.Current.GetInstance<RowMapperCache>()
.GetCachedMapper<Region>();
var db = EnterpriseLibraryContainer.Current.GetInstance<Database>();
return db.ExecuteSqlStringAccessor<Region>("SELECT * FROM Region", regionMapper).ToList();
}
}
}