Voici un hack facile et agréable suggéré par l'équipe d'assistance d'entlib (vous pouvez consulter le fil de discussion complet à l'adresse suivante http://entlib.codeplex.com/discussions/281833 ) :
randylevy Lun à 11:39 PM Non, il n'y a pas de mise en cache du RowMapper. La seule mise en cache que je connaisse pour l'accès aux données est la suivante Application Block est la mise en cache des paramètres de la procédure stockée.
Si vous utilisez le mappeur par défaut, vous pouvez mettre les résultats en cache. et les passer dans la méthode ExecuteSqlStringAccessor puisqu'elle supporte supporte les surcharges IRowMapper et IResultSetMapper.
Par exemple :
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);
UPDATE De nouveau à partir d'EntLib (une solution encore meilleure) :
Merci. Peut-être que cela peut être mis sur la table pour Enterprise Library 6 puisque cela semble être une bonne idée ?
Juste pour le fun, j'ai un peu affiné l'exemple pour stocker le RowMapperCache en tant que singleton à l'intérieur de l'EnterpriseLibraryContainer de façon à ce qu'il puisse être récupéré comme les autres objets de l'Enterprise Library. Bien que bien qu'il ne s'agisse pas d'une classe "native" de l'Enterprise Library, le RowMapperCache est utilisé uniquement avec Enterprise Library. Il n'est donc pas nécessaire de la stocker dans le conteneur le conteneur (surtout si vous n'utilisez pas l'IoC complet de Unity).
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();
}
}
}