繁体   English   中英

使用Asp.net Boilerplate在Entity Framework中进行多对多关系复制记录

[英]Duplicating record in Entity Framework many to many relationship using Asp.net Boilerplate

我在实体框架中使用asp.net样板。 我有2个实体:具有多对多关系的产品和供应商。

我的问题:当我与一个或多个供应商保存产品时,会保存该产品及其在SupplierProduct表上的关系,但供应商记录会在Supplier表上重复。

我读到这种情况是因为有2个来自不同上下文的实体,所以我需要将供应商“附加”到Products上下文。 我不知道该怎么做。 有人可以帮我吗?

我的实体:

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; }
}

我的域名服务称为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);
        }
    }

我的应用程序服务称为ProductAppService:

public async Task Create(CreateProductInput input)
    {
        Product output = Mapper.Map<CreateProductInput, Product>(input);
        await _productManager.Create(output);
    }

我的CreateProductInput数据传输对象

public class CreateProductInput
{
    public string Name { get; set; }

    public ICollection<Supplier> Suppliers { get; set; }
}

我的角度组件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();
            });
    }

我认为问题在于create方法中发生了什么以及您将传递给它什么。

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);
    }
}

在我看来,您传递给Create方法的参数始终具有Id == 0,因此为什么它将始终落入else块并插入新实体

那是因为CreateProductInput没有要映射的Id属性。 因此,它将始终映射到具有默认值Id(int = 0)的产品。

另外,您可以传递供应商实体的ID并在调用Create之前获取它们,这样,这些实体应自动附加到DbContext上,而不要重复

根据Ivan Stoev的评论,我想出了解决方法。 我实现了一个自定义存储库,并将我的实体附加到那里的dbcontext中。

该链接详细显示了如何创建自定义存储库。

在简历中:

1-创建一个自定义的存储库接口

2-实施自定义存储库+

3-在dbcontext.attach(entity)创建一个方法,然后使用dbcontext.attach(entity)将复制的实体附加到上下文并保存该上下文。

4-将用于域服务的IRepository替换为自定义存储库。

5-使用自定义创建的方法,并感到高兴。

如果消息不够清晰,请在此处查看消息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM