Hi @hikalkan,
maybe i have misunderstood slightly.
What my end goal is to implement an overload of InsertOrUpdate which accepts an IEnumerable as a parameter, so it does a bulk insert or update. I want to implement this for any entities that use the IRepository interface.
Is this possible in the Framework, or would i have to implement a custom repository for each entity and duplicate the logic?
Here is a code example of the method i am trying to implement for all repositories
public async Task InsertOrUpdateAsync(List<TEntity> entities)
{
var entitiesToAdd = new List<TEntity>();
Context.Configuration.AutoDetectChangesEnabled = false;
foreach (var account in entities)
{
entitiesToAdd.Add(account);
if (entitiesToAdd.Count % 500 != 0)
{
continue;
}
Context.Set<TEntity>().AddOrUpdate(entitiesToAdd.ToArray());
entitiesToAdd = new List<TEntity>();
Context.ChangeTracker.DetectChanges();
await Context.SaveChangesAsync();
Context.DetachAll();
}
Context.Set<TEntity>().AddOrUpdate(entitiesToAdd.ToArray());
Context.ChangeTracker.DetectChanges();
await Context.SaveChangesAsync();
Context.DetachAll();
}
Many thanks
@ismcagdas What would define an Id field? If it is just a field named "Id" then i can't think of any that would have duplicates.
Here is a bit of the controller code
[HttpPost]
[UnitOfWork]
public virtual async Task<ActionResult> CreateUser(CreateUserViewModel model)
{
try
{
CheckModelState();
// Validation code removed
// Switch to the tenant
if (tenant != null)
{
_unitOfWorkManager.Current.EnableFilter(AbpDataFilters.MayHaveTenant);
_unitOfWorkManager.Current.SetTenantId(tenant.Id);
}
// Add default roles
user.Roles = new List<UserRole>();
var roles = await _roleManager.Roles.Where(r => r.IsDefault).ToListAsync();
if (roles.Any())
{
foreach (var defaultRole in roles)
{
user.Roles.Add(new UserRole { RoleId = defaultRole.Id });
}
}
// Save User
CheckErrors(await _userManager.CreateAsync(user));
await _unitOfWorkManager.Current.SaveChangesAsync();
}
catch (UserFriendlyException ex)
{
ViewBag.ErrorMessage = ex.Message;
return View("CreateUser", model);
}
}
I've removed some validation code at the top as this works. Just on another note as well, if i comment out the code that throws the exception, then another slice of code also throws the same exception
CheckErrors(await _userManager.CreateAsync(user));
Thanks
Resolved after upgrading to v0.9.3.0. Many Thanks
I've done a bit more testing this morning just to try and rule a few things out.
I've setup a brand new EF project (no abp packages installed) and it can pull a list of Contacts out fine.
I've changed the code slightly just to see if it was pulling them all out at the same time that was the issue. Here is the new code.
[UnitOfWork]
protected override void DoWork()
{
//var contacts = _autoTaskContactRepository.GetAllList();
var totalContacts = _autoTaskContactRepository.Count();
var pages = Math.Ceiling(Convert.ToDouble(totalContacts)/500);
var contacts = new List<AutoTaskContact>();
for (int i = 0; i < pages; i++)
{
contacts.AddRange(_autoTaskContactRepository.GetAll().OrderBy(c => c.AccountID).Skip(i * 500).Take(500));
}
Debug.WriteLine("{0} Contacts", contacts.Count);
}
If i loop through the iteration with breakpoints, i can see that it is working, however each loop takes longer and longer to complete. I also fire up sql profiler and i can see the actual sql command completes in no time at all, but the time between each request gets longer and longer.
I can actually get it to run now if i change the code to this
//[UnitOfWork]
protected override void DoWork()
{
//var contacts = _autoTaskContactRepository.GetAllList();
var totalContacts = _autoTaskContactRepository.Count();
var pages = Math.Ceiling(Convert.ToDouble(totalContacts)/500);
var contacts = new List<AutoTaskContact>();
for (int i = 0; i < pages; i++)
{
using (var unitOfWork = _unitOfWorkManager.Begin())
{
contacts.AddRange(_autoTaskContactRepository.GetAll().OrderBy(c => c.AccountID).Skip(i * 500).Take(500));
unitOfWork.Complete();
}
}
Debug.WriteLine("{0} Contacts", contacts.Count);
}
but it still takes a relatively long time to complete, 1 minute 34 to bring 9207 records out of sql.
Cheers
Thanks! I was on the right lines with the modelBuilder but my syntax was slightly off.
Github issue raised
<a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/issues/997">https://github.com/aspnetboilerplate/as ... issues/997</a>
Many Thanks!
Yes it is, here is Controller
[HttpPost]
public async Task<JsonResult> UpdateCloudRepositoryContract(SplaVeeamCloudRepositoryContractUpdateViewModel model)
{
CheckModelState();
DoStuf();
return Json(new {ContractId = model.Id});
}
Thanks
Apologies, i just misread the documentation! Its working now, just injected it into the class. Many Thanks