2011-05-03 2 views
3

Вот сценарий. Различные пользователи вносят изменения, выбирая значение из выпадающего списка на веб-странице. Выпадающее содержимое содержится либо в DataView, либо путем построения таблицы. Если Пользователь А вносит изменения в строку 1, он обновляет базу данных и показывает их изменения после перезаписи. Впоследствии пользователь B находится на одной странице, когда пользователь A делает их изменения и вносит изменения в строку 2. База данных обновляется, а gridview восстанавливается (или таблица перестраивается). Однако пользователь B не видит изменения, внесенные пользователем A. Я предполагаю, что это связано с кэшированием EF. Если пользователь обновляет страницу (или перенаправляется обратно на нее), они могут видеть последние данные в базе данных.Как вы обновляете кешированный EF из базы данных после SaveChanges?

Как я могу получить последние данные из базы данных без обновления страницы?

Метод, который связывает называется в Pageload каждый раз включая постбэка:

private void PopulateFormForDealer(DateTime BeginDate, DateTime EndDate, int DealerID, bool UnVerifiedOnly) 
    { 
     try 
     {     
     using (var DB = new NIMSModel.NIMSEntities()) 
     { 

    var scheduledOrders = from r in DB.Reservations 
       join o in DB.Orders on r.ResID equals o.ReservationID 
       where r.ResDate <= EndDate && r.ResDate >= BeginDate && r.Claimed == "Y" 
       && r.DealerID == DealerID //&& r.Verified == VerifiedOnly 
       orderby r.ResDate, r.ResID 
       select new { r.ResID, o.ID, o.VantiveOrderID, o.CustomerFirstName, o.CustomerCity, o.CustomerState, o.CustomerZipCode, o.OrderType.Type, r.ResDate, r.TimeOfDay, r.Source, DealerInstallerID = r.DealerInstallerID == null ? 0 : r.DealerInstallerID, r.Verified, r.Notes }; 


    GridView1.DataSource = scheduledOrders.ToList(); 
    GridView1.DataBind(); 

} 
} 
catch (Exception ex) 
{ 
LogError(ex); 
} 

}

Вот обработчик события для выпадающего списка:

protected void ddInstaller_SelectedIndexChanged(Object sender, EventArgs e) 
    { 
     try 
     { 
string foo = ((DropDownList)sender).SelectedValue; 
Guid theg = new Guid(((DropDownList)sender).SelectedValue.Split('_')[1].ToString()); 
int? installerid = int.Parse(((DropDownList)sender).SelectedValue.Split('_')[0].ToString()); 
string installername = ((DropDownList)sender).SelectedItem.Text; 

if (installerid == 0) 
{ 
    installerid = null; 
} 

int testvalidguidlen = theg.ToString().Replace("0", "").Length; 
if (testvalidguidlen > 10) 
{ 
    string note; 
    using (var DB = new NIMSModel.NIMSEntities()) 
    { 
    var reservatoins = DB.Reservations.Where(r => r.ResID == theg).FirstOrDefault(); 

    if (reservatoins.DealerInstallerID != installerid) 
    { 
     var orders = DB.Orders.Where(o => o.ReservationID == theg).FirstOrDefault(); 

     reservatoins.DealerInstallerID = installerid; 
     orders.InstallerID = installerid; 

     if (reservatoins.Notes == null || reservatoins.Notes.Length >= 1800) 
     { 
     note = "[" + DateTime.Now.ToString("yyyy.MM.dd hh:mm:ss") + "] TechChange by: " + PTNAccount.UserName + "(" + PTNAccount.LoginID + "); NewTech: " + installername + ";"; 
     } 
     else 
     { 
     note = reservatoins.Notes + "[" + DateTime.Now.ToString("yyyy.MM.dd hh:mm:ss") + "] TechChange by: " + PTNAccount.UserName + "(" + PTNAccount.LoginID + "); NewTech: " + installername + ";"; 
     } 
     reservatoins.Notes = note; 

     DB.SaveChanges(); 
    } 
    } 
} 
} 
catch (Exception ex) 
{ 
LogError(ex); 
} 

}

Здесь мы используем метод, который создает drop dow п список:

private DropDownList PopulateInstallerDropDownList(DropDownList ddl, String resID) 
    { 

try 
{ 
using (var DB = new NIMSModel.NIMSEntities()) 
{ 
    var DealerInstallers = from di in DB.DealerInstallers 
       where di.Active == 1 && di.IsDeleted == "N" && di.DealerID == DealerID 
       orderby di.Name 
       select new { di.ID, di.Name }; 
    var DealerInstallersArray = DealerInstallers.ToArray(); 
    ListItem li = new ListItem("","0_" + resID); 
    ddl.Items.Add(li); 

    foreach (var installer in DealerInstallersArray) 
    { 
    ddl.Items.Add(new ListItem(installer.Name.ToString(), (installer.ID.ToString() + (string)"_" + resID.ToString()))); 
    } 
} 
} 
catch (Exception ex) 
{ 
string foo = ex.Message; 
} 
return ddl; 

}

Вот обработчик события RowDataBound:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) 
{ 

if (e.Row.RowType == DataControlRowType.DataRow) 
{ 
string reservationID = DataBinder.Eval(e.Row.DataItem, "ResID").ToString(); 
DropDownList ddl = (DropDownList)e.Row.FindControl("ddInstaller"); 
PopulateInstallerDropDownList(ddl, reservationID); 
string dealerInstallerId = DataBinder.Eval(e.Row.DataItem, "DealerInstallerID").ToString(); 

if (dealerInstallerId != "0") 
{ 
    dealerInstallerId = dealerInstallerId + "_" + reservationID; 
} 

if (dealerInstallerId.Length > 1) 
{ 
    ddl.SelectedIndex = ddl.Items.IndexOf(ddl.Items.FindByValue(dealerInstallerId)); 
} 
} 
} 

Я сделал несколько запросов для решения в течение последних двух дней. Любая помощь приветствуется.

+2

Я уверен, что это не имеет ничего общего с кэшированием EF вообще, по умолчанию нет кэширования данных, если вы не используете пользовательский поставщик кэширования. – BrokenGlass

+0

Как часто изменяются данные и насколько важно, чтобы пользователи имели самую актуальную информацию прямо сейчас? Самое простое решение - панель обновления по таймеру. Но этого вам будет достаточно? – Chad

+0

Вы на 100% уверены, что используете метод привязки для обратной передачи? Поскольку ToList() всегда будет вызывать запрос, и, как сказал BitkenGlass, кеширование данных по умолчанию отсутствует. – hyp

ответ

0

Пользователь B не видит изменения, сделанные пользователем А поскольку изменения пользователя B переписал изменение, сделанное пользователем А.

То, что вы хотите сделать, это осуществить проверку параллелизма в вашей системе. Поэтому, когда пользователь A и Пользователь B извлекают один и тот же экземпляр объекта в базе данных, первый человек, который внесет изменения и отправит в базу данных, будет успешным. Изменения, внесенные вторым лицом, не будут устранены с помощью исключения параллелизма - поскольку ваша бэкэнд-система обнаружит, что Пользователь B внес изменения в «устаревший» объект, который был изменен предыдущим изменением.

Поскольку вы используете EF, вам повезло, потому что у него есть хорошая система, которая управляет параллелизмом для вас. Выберите свойство в своей сущности для проверки на параллелизм - обычно это «Последняя измененная дата» объекта.

Открыть файл EDMX, щелкнуть нужное свойство, которое вы хотите использовать для проверки параллелизма (например, LastDateModified), и установить ConcurrencyMode = Fixed.

1

Entity Framework 3.5 сохраняет изменения в невероятном виде, но фиксируется в EF 4.0 Я думаю, что ваш с помощью EF 3,5

Hover вы должны знать, что случится с вашими данными и как EF сохранить данные. вы можете прочитать MSDN об этой проблеме.

В настоящее время вы можете вызвать метод обновления для обновления данных, когда вы SaveChanges.

context.Refresh(RefreshMode.ClientWins, orders); 

EF 4,0> EF 3,5

Смежные вопросы