2015-02-18 4 views
0

В моем проекте 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 обновляться одновременно? Я что-то пропустил здесь?

+0

Возможно, это кеш браузера? –

+0

Попробуйте отключить ASPxGridView.EnableRowsCache (https://documentation.devexpress.com/#AspNet/DevExpressWebASPxGridView_EnableRowsCachetopic) –

+0

APSxGridView.EnableRowsCache не является проблемой. Я сузил, что необработанные данные, поступающие из NHibernate, содержат правильное, актуальное значение, но AutoMapper каким-то образом кэширует предыдущее значение. Вызов Automapper.Mapper.Reset() вызовет исключение «Конфигурация карты отсутствующего типа или неподдерживаемое отображение». – mckennawebdev

ответ

0

Решение, которое я нашел, состояло в том, чтобы вызвать DataBase.Clear(), существенно очистив кэш уровня NHibernate первого уровня перед заполнением объекта EntityOneRaw, как в следующем примере. Мои преимущества использования кеширования первого уровня, поэтому в моем фактическом коде я вызываю только метод Clear() по мере необходимости.

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) 
     { 
      DataBase.Clear(); //clear the first-level cache in NHibernaet 
      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 
     } 
    } 
} 
Смежные вопросы