В моем проекте WebForms используется библиотека классов NHibernate в качестве OR-преобразователя для наших баз данных Oracle. Библиотека NHibernate полностью протестирована и работает без каких-либо проблем.Automapper С NHibernate и DevExpress GridView - Кэширование
Global.asax.cs:
void Application_Start(object sender, EventArgs e)
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
var cnnConfig = ""; //contains connection string information for NH
NHibernateClassLibrary.init(cnnConfig); //initializes NHibernate
var profileType = typeof(AutoMapper.Profile);
// Get an instance of each Profile in the executing assembly.
var profiles = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => profileType.IsAssignableFrom(t)
&& t.GetConstructor(Type.EmptyTypes) != null)
.Select(Activator.CreateInstance)
.Cast<Profile>();
// Initialize AutoMapper with each instance of the profiles found.
Mapper.Initialize(a => profiles.ForEach(a.AddProfile)); //ForEach is an extension method
}
ExtensionMethods.cs:
public static class ExtensionMethods
{
public static void ForEach<T>(this IEnumerable<T> enumerable,
Action<T> action)
{
foreach (T item in enumerable) { action(item); }
}
}
SampleProfile.cs:
namespace MyProjectName.AutomapperProfiles
{
public class EntityOneProfile : Profile
{
protected override void Configure()
{
base.Configure();
Mapper.CreateMap<NHibernateClassLibrary.Entities.EntityOne, EntityOnePoco>();
}
}
}
EntityOne.cs:
namespace NHibernateClassLibrary.Entities
{
public class EntityOne
{
public virtual string PropertyOne { get; set; }
public virtual string PropertyTwo { get; set; }
public virtual string PropertyThree { get; set; }
}
}
EntityOnePoco.cs:
namespace MyProjectName.GridEntities
{
public class EntityOnePoco
{
public string PropertyOne { get; set; }
public string PropertyTwo { get; set; }
public string PropertyThree { get; set; }
}
}
MyPage.aspx.cs:
namespace MyProjectName
{
public partial class MyPage : System.Web.UI.Page
{
//This gets us access to the NHibernate Class Library
IDATABASE DataBase = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IDATABASE>();
protected void Page_Load(object sender, EventArgs e)
{
var EntityOneRaw = DataBase.EntityOne.ToList();
var EntityOneObjects = EntityOneRaw.Select(q => AutoMapper.Mapper.Map<NHibernateClassLibrary.Entities.EntityOne, EntityOnePoco>(q)).ToList();
GridViewObject.DataSource = new BindingList<EntityOnePoco>(EntityOneObjects);
GridViewObject.DataBind();
}
protected void ButtonOne_Click(object sender, EventArgs e)
{
var Item = DataBase.EntityOne.First();
Item.PropertyTwo = "New Value";
DataBase.SaveChanges(); //NHibernate call to commit
}
}
}
MyPage.aspx:
<!--Other lines truncated-->
<dx:ASPxGridView ID="GridViewObject" runat="server" KeyFieldName="PropertyOne">
</dx:ASPxGridView>
<asp:Button ID="ButtonOne" runat="server" Text="Take Action" OnClick="ButtonOne_Click" />
Page_Load метод отлично работает. Сетка загрузится с текущими значениями базы данных, например, «PropertyTwo» первой записи, равной, например, «Старая ценность». Если я нажму кнопку ButtonOne, метод ButtonOne_Click будет запускать и обновлять первую запись в таблице EntityOne соответствующим образом. Я подтвердил это прямо в Oracle. Кроме того, точка останова, установленная сразу после завершения этого действия, показывает, что NHibernateClassLibrary соответствующим образом извлекает новое свойство. Тем не менее, GridView по-прежнему отображает «Старое значение», пока я не остановлю IIS/Отладка и перезагрузка.
Мой первый инстинкт заключается в том, что кеширование разрешено где-то, но я подтвердил, что NHibernate не кэширует старое значение. Если EntityOne из базы данных обновлен, как я могу заставить AutoMapped EntityOnePoco обновляться одновременно? Я что-то пропустил здесь?
Возможно, это кеш браузера? –
Попробуйте отключить ASPxGridView.EnableRowsCache (https://documentation.devexpress.com/#AspNet/DevExpressWebASPxGridView_EnableRowsCachetopic) –
APSxGridView.EnableRowsCache не является проблемой. Я сузил, что необработанные данные, поступающие из NHibernate, содержат правильное, актуальное значение, но AutoMapper каким-то образом кэширует предыдущее значение. Вызов Automapper.Mapper.Reset() вызовет исключение «Конфигурация карты отсутствующего типа или неподдерживаемое отображение». – mckennawebdev