I have a service layer returning a collection of entities :
/// <summary>
/// Returns list of all existing accounts.
/// </summary>
IList<Account> GetAllAccounts();
This is called on UI layer to get IList collection and bind it to UI via IBindingList :
public BindingList<Account> Accounts
{
get;
private set;
}
public void LoadAccounts()
{
var service = IoC.Resolve<IAccountService>();
Accounts = new BindingList<Account>(service.GetAllAccounts());
}
Then UI changes the the IBindingList collection (adding, deleting and editing entities), so at some point (before saving) we have a collection that has edited, deleted and new entities. How can I save this collection in a way to avoid unnecessary updates (do not update entities that are not changed). When I do the following, an Insert / Update / Delete statement is ran for ALL items in the collection:
on UI :
public void Save()
{
var accountService = IoC.Resolve();
accountService.Update(Accounts);
}
on Service Layer:
public void Update(IList<Account> accounts)
{
if (accounts == null || accounts.Count == 0)
return;
using (UnitOfWork.Start())
using (var session = UnitOfWork.CurrentSession)
using (var tx = session.BeginTransaction())
{
foreach (var acc in accounts)
{
if (acc.AccountId == 0)
{
session.Save(acc);
}
else
{
session.Update(acc);
}
}
tx.Commit();
}
}
Note that entities are some POCO classes. Is there any way to know if a collection has changes, or an easy way to find if the entity is dirty (HasChanges or IsDirty kinda thing).
If the objects were loaded in the same session, then the session is keeping track of changed objects and update only the changed ones. But in your case the objects are not associated with this session.
You could track the changed objects yourself and save or update the changed ones. NHibernate cannot help you there.
Or you could try and implement Session per Conversation pattern and keep the objects in one session over multiple requests.
As a side note you could use the ISession.SaveOrUpdate(Object) method instead of the if statement. The session will do it for you ;).