简体   繁体   English

使用存储库模式在实体框架中添加具有相关子对象的记录

[英]Adding record with related child object in Entity Framework using Repository Pattern

I have trouble with adding an entity to database which contains an relation to existing object.我无法将实体添加到包含与现有对象的关系的数据库中。 I searched alot and couldn't find proper solution for this.我搜索了很多,找不到合适的解决方案。 I will describe this as simple as I can.我将尽可能简单地描述这一点。

public class Store : IEntity
{
    public int StoreId { get; set; }
    public string StoreName { get; set; }

    public virtual Address Address { get; set; }

    public virtual Contractor Contractor { get; set; }
}

    public class Product : IEntity
{
    public int ProductId { get; set; }
    public string ProductName { get; set; }
    public decimal Price { get; set; }
    public virtual Store Store { get; set; }
}

And in repository im adding records like this.在存储库中,我添加了这样的记录。 This is generic class这是泛型类

        public TEntity Add(TEntity entity)
    {
        using (var context = new TContext())
        {
            var addedEntity = context.Entry(entity);
            addedEntity.State = EntityState.Added;
            context.SaveChanges();
            return entity;
        }
    }

Now when i try to add new record like this现在当我尝试像这样添加新记录时

var store = storeManager.GetBy(x => x.StoreId == 1);

var product = new Product() { ProductName = "Bananas", Store = store }; 

productManager.Add(product);

productManager.GetAll().ForEach(x => Console.WriteLine(x.ProductName + " " + x.Store.StoreId));

Store relation is added as new store and it get's new ID.商店关系被添加为新商店并获得新的 ID。 Does someone have idea how i can solve this?有人知道我该如何解决这个问题吗?

Example from database:来自数据库的示例:

StoreId StoreName   Address_AddressId   Contractor_ContractorId
1   NULL    1   1
2   NULL    2   2
3   NULL    3   3
4   NULL    4   4
5   NULL    5   5
6   NULL    6   6
7   NULL    7   7

It's my first question on stackoverflow.这是我关于stackoverflow的第一个问题。

The most probable cause of your issue is that you are creating a new instance of your context for the insert opreration.问题的最可能原因是您正在为插入操作创建上下文的新实例 Because of that, this new context not only gets a new product but also a store, which is received from another context, but this newly created context doesn't have any idea the store is already in the database.正因为如此,这个新上下文不仅获得了一个新产品,而且还获得了一个从另一个上下文接收的商店,但是这个新创建的上下文不知道商店已经在数据库中了。

A general issue then is incorrect managing the lifecycle of your database contexts.一个普遍的问题是不正确地管理数据库上下文的生命周期。 EF instances are tied to contexts that were used to receive them and you can't just put an entity from a context into another context. EF 实例与用于接收它们的上下文相关联,您不能只是将一个实体从一个上下文放入另一个上下文。

Instead of creating a new context in each of your manager operations, you should share the instance of the database context between multiple managers.您应该在多个管理器之间共享数据库上下文的实例,而不是在每个管理器操作中创建新上下文。

public class StoreManager
{
     public StoreManager( Context context )
     {
         this.context = context;
     }

   public TEntity Add(TEntity entity)
   {
        var addedEntity = context.Entry(entity);
        addedEntity.State = EntityState.Added;
        context.SaveChanges();
        return entity;
    }
}

The orchestration has to first create the context and make sure it's shared between the two managers编排必须首先创建上下文并确保它在两个管理器之间共享

var context = new DbContext();

var storeManager   = new StoreManager( context );
var productManager = new ProductManager( context );

var store = storeManager.GetBy(x => x.StoreId == 1);
var product = new Product() { ProductName = "Bananas", Store = store }; 

productManager.Add(product);

productManager.GetAll().ForEach(x => Console.WriteLine(x.ProductName + " " + 
    x.Store.StoreId));

Usually, all these are created in a single scope, eg in a request scope, so that a single web request has a single database context and each repositories get the very same instance of the context.通常,所有这些都是在单个作用域中创建的,例如在请求作用域中,因此单个 Web 请求具有单个数据库上下文,并且每个存储库都获得完全相同的上下文实例。

You can also follow an official tutorial .您也可以按照官方教程进行操作

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

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