Im using asp.net boilerplate with entity framework. I have 2 entities: Product and Supplier with many to many relationship.
My problem: When i save a product with one or more suppliers, The product and the relation on supplierProduct table is saved but the supplier record is duplicated on supplier table.
I read that happens because there are 2 entities from different contexts, so i need "attach" the suppliers to Products context. I dont know how to do it. Someone can help me?
My entities:
public class Product : FullAuditedEntity
{
public Product()
{
Suppliers = new HashSet<Supplier>();
}
public string Name { get; set; }
public virtual ICollection<Supplier> Suppliers { get; set; }
}
public class Supplier : FullAuditedEntity
{
public Supplier()
{
Products = new HashSet<Product>();
}
public string Name { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
My domain service called ProductManager
public async Task<Product> Create(Product entity)
{
var product = _repositoryProduct.FirstOrDefault(x => x.Id == entity.Id);
if (product != null)
{
throw new UserFriendlyException("Product already exists.");
}
else
{
return await _repositoryProduct.InsertAsync(entity);
}
}
My Application Service called ProductAppService:
public async Task Create(CreateProductInput input)
{
Product output = Mapper.Map<CreateProductInput, Product>(input);
await _productManager.Create(output);
}
My CreateProductInput Data transfer object
public class CreateProductInput
{
public string Name { get; set; }
public ICollection<Supplier> Suppliers { get; set; }
}
My angular component product-list-component
// GET Products
function getProducts() {
productService.listAll()
.then(function (result) {
vm.users = result.data;
});
}
getProducts();
// GET Suppliers
function getSuppliers() {
supplierService.listAll()
.then(function (result) {
vm.suppliers = result.data;
});
}
getSuppliers();
//Save the data
vm.save = function () {
abp.ui.setBusy();
productService.create(vm.product)
.then(function () {
abp.notify.info(App.localize('SavedSuccessfully'));
$uibModalInstance.close();
}).finally(function () {
abp.ui.clearBusy();
getProducts();
});
}
Following the Ivan Stoev comment i figure out how solve it. I implemented a custom repository and attached my entities to the dbcontext there.
This link shows in details how create a custom repository.
In resume:
1- Create a custom repository INTERFACE
2- Implement the custom repository+
3- Create a method there and use the dbcontext.attach(entity)
to attach to the context the entity thats was duplicating and save the context.
4- Replace the IRepository used on domain service for the custom repository.
5- Use the custom created method and be happy.
Msg here if its not clear enough.