C# enterprise library 5.0是否缓存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

想知道Enterprise Library 5.0的访问器方法是否缓存datareader的字段以及自定义类以提高性能,从而在将datareader映射到对象时不会使用反射查找自定义类上的字段名,也不会查找datareader上的字段名?因为对于每个访问/代码块,将自定义类字段映射到datareader字段是一项非常昂贵的操作

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