C# EF数据访问层中的IEntityChangeTracker的多个实例无法引用实体对象

C# EF数据访问层中的IEntityChangeTracker的多个实例无法引用实体对象,c#,asp.net,entity-framework,architecture,data-layer,C#,Asp.net,Entity Framework,Architecture,Data Layer,我见过很多关于同一主题的问题,但至今还没有找到解决办法。给我带来问题的代码是: public async Task<IHttpActionResult> Post(FullOrderViewModel fullOrder) { //Get all order items List<OrderItem> orderItems = new List<OrderItem>(); foreach (var

我见过很多关于同一主题的问题,但至今还没有找到解决办法。给我带来问题的代码是:

    public async Task<IHttpActionResult> Post(FullOrderViewModel fullOrder)
    {
        //Get all order items
        List<OrderItem> orderItems = new List<OrderItem>();
        foreach (var oi in fullOrder.Order)
        {
            var color = _colorRepo.Find(oi.ColorId);
            var item = new OrderItem
            {
                Quantity = oi.Quantity,
                Color = color
            };
            orderItems.Add(item);
        }

        //Get customer id
        var customer = await _adminRepo.GetCustomerByUserName(fullOrder.Customer.UserName);

        var billAddress = _addressRepo.All.FirstOrDefault(x => x.AddressLine == fullOrder.BillingAddress.AddressLine && x.PostalCode == fullOrder.BillingAddress.PostalCode);
        var deliveryAddress = _addressRepo.All.FirstOrDefault(x => x.AddressLine == fullOrder.DeliveryAddress.AddressLine && x.PostalCode == fullOrder.DeliveryAddress.PostalCode);

        //CASE : sample order
        if (fullOrder.OrderType == OrderType.Sample)
        {
            var order = new SampleOrder {
                Type = OrderType.Sample,
                Status = "Unauthorized",
                Origin = Origin.Online,
                OrderItems = orderItems,
                CreationDate = DateTime.Now,
                CustomerId = customer.Id,
                BillAddressId = billAddress.AddressId,
                DeliveryAddressId = deliveryAddress.AddressId
            };
            try
            {
                _sampleOrderRepo.InserGraph(order);
                _unitOfWork.Save();
            }
            catch (Exception e)
            {
                return InternalServerError(e);
            }
公共异步任务发布(FullOrderViewModel fullOrder)
{
//获取所有订单项目
List orderItems=新列表();
foreach(完整订单中的var oi.Order)
{
var color=_colorRepo.Find(oi.ColorId);
var item=新订单项
{
数量=oi.数量,
颜色=颜色
};
orderItems.Add(item);
}
//获取客户id
var customer=wait_adminRepo.GetCustomerByUserName(fullOrder.customer.UserName);
var billAddress=\u addressRepo.All.FirstOrDefault(x=>x.AddressLine==fullOrder.BillingAddress.AddressLine&&x.PostalCode==fullOrder.BillingAddress.PostalCode);
var deliveryAddress=\u addressRepo.All.FirstOrDefault(x=>x.AddressLine==fullOrder.deliveryAddress.AddressLine&&x.PostalCode==fullOrder.deliveryAddress.PostalCode);
//案例:样品订单
if(fullOrder.OrderType==OrderType.Sample)
{
变量顺序=新样本顺序{
Type=OrderType.Sample,
Status=“未经授权”,
来源=来源。在线,
OrderItems=OrderItems,
CreationDate=日期时间。现在,
CustomerId=customer.Id,
BillAddressId=billAddress.AddressId,
DeliveryAddressId=deliveryAddress.AddressId
};
尝试
{
_sampleOrderRepo.InserGraph(订单);
_unitOfWork.Save();
}
捕获(例外e)
{
返回内部服务器错误(e);
}
我获取存储库的方式是通过OrderController构造函数中的依赖项注入,因此我相信这是一种标准的方式。我的每个repo都是以这种方式构建的:

public class SampleOrderRepository : EntityRepository<SampleOrder, IPhoeniceUnitOfWork<PhoeniceContext>>, ISampleOrderRepository
{
    public SampleOrderRepository(IPhoeniceUnitOfWork<PhoeniceContext> unitOfWork) : base(unitOfWork)
    {
    }

    protected override IDbSet<SampleOrder> List(IPhoeniceUnitOfWork<PhoeniceContext> unitOfWork)
    {
        return unitOfWork.Context.SampleOrders;
    }

    protected override Expression<Func<SampleOrder, bool>> FindInt(int id)
    {
        return x => x.OrderId == id;
    }
}
公共类SampleOrderRepository:EntityRepository,ISampleOrderRepository
{
公共SampleOrderRepository(IPhoeniceUnitOfWork unitOfWork):基础(unitOfWork)
{
}
受保护的覆盖IDbSet列表(IPhoeniceUnitOfWork unitOfWork)
{
返回unitOfWork.Context.SampleOrders;
}
受保护的重写表达式FindInt(int-id)
{
返回x=>x.OrderId==id;
}
}
其中我覆盖了通用实体存储库中的方法:

public abstract class EntityRepository<T, TContext> : IEntityRepository<T> 
    where T : class, IObjectWithState
    where TContext : IUnitOfWork<EntityContext>
{
    protected readonly TContext _unitOfWork;

    protected EntityRepository(TContext unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    protected virtual IDbSet<T> List(TContext unitOfWork)
    {
        throw new NotImplementedException("List operation not implemented!");
    }

    protected virtual Expression<Func<T, bool>> FindInt(int id)
    {
        throw new NotImplementedException("Finding entity with an int is not implemented!");
    }

    protected virtual Expression<Func<T, bool>> FindString(string id)
    {
        throw new NotImplementedException("Finding entity with an int is not implemented!");
    }

    public virtual IQueryable<T> All { get { return List(_unitOfWork); } }

    public virtual IQueryable<T> AllIncluding(params Expression<Func<T, object>>[] includeProperties)
    {
        return includeProperties.Aggregate(All, (current, includeProperty) => current.Include(includeProperty));
    }

    public virtual T Find(int id)
    {
        return All.FirstOrDefault(FindInt(id));
    }

    public virtual T FindByString(string id)
    {
        return All.FirstOrDefault(FindString(id));
    }

    public virtual void InserGraph(T entity)
    {
        List(_unitOfWork).Add(entity);
    }

    public void InsertOrUpdate(T entity)
    {
        if (entity.ObjectState == State.Added) // New entity
        {
            _unitOfWork.Context.Entry(entity).State = EntityState.Added;
        }
        else        // Existing entity
        {
            _unitOfWork.Context.Entry(entity).State = EntityState.Modified;
            _unitOfWork.Context.ApplyStateChanges();
        }
    }

    public virtual void Delete(int id)
    {
        var entity = Find(id);
        List(_unitOfWork).Remove(entity);
    }

    public void Dispose()
    {

    }
}
公共抽象类EntityRepository:EntityRepository
其中T:class,IObjectWithState
where t上下文:i工作单元
{
受保护的只读上下文\u工作单元;
受保护的实体存储库(TContext unitOfWork)
{
_unitOfWork=unitOfWork;
}
受保护的虚拟IDbSet列表(TContext unitOfWork)
{
抛出新的NotImplementedException(“列表操作未实现!”);
}
受保护的虚拟表达式FindInt(int-id)
{
抛出新的NotImplementedException(“未实现查找具有int的实体!”);
}
受保护的虚拟表达式查找字符串(字符串id)
{
抛出新的NotImplementedException(“未实现查找具有int的实体!”);
}
公共虚拟IQueryable所有{get{return List(_unitOfWork);}
公共虚拟可查询AllIncluding(参数表达式[]包含属性)
{
返回includeProperty.Aggregate(全部,(当前,includeProperty)=>current.Include(includeProperty));
}
公共虚拟内存找不到(int-id)
{
返回所有.FirstOrDefault(FindInt(id));
}
公共虚拟T FindByString(字符串id)
{
返回所有.FirstOrDefault(FindString(id));
}
公共虚拟虚空插入图(T实体)
{
列表(工作单元)。添加(实体);
}
公共作废插入更新(T实体)
{
if(entity.ObjectState==State.Added)//新实体
{
_unitOfWork.Context.Entry(entity).State=EntityState.Added;
}
else//现有实体
{
_unitOfWork.Context.Entry(entity).State=EntityState.Modified;
_unitOfWork.Context.ApplyStateChanges();
}
}
公共虚拟无效删除(int-id)
{
var实体=查找(id);
列表(工作单元)。删除(实体);
}
公共空间处置()
{
}
}
最后,这是我的UnitOfWork项:

public class PhoeniceUnitOfWork : IPhoeniceUnitOfWork<PhoeniceContext>
{
    private readonly PhoeniceContext _context;

    public PhoeniceUnitOfWork() : base()
    {
        _context = new PhoeniceContext();
    }

    //Left for testing purposes
    public PhoeniceUnitOfWork(PhoeniceContext context)
    {
        _context = context;
    }

    public int Save()
    {
        return _context.SaveChanges();
    }

    public void Dispose()
    {
        _context.Dispose();
    }

    public IAddressRepository AddressRepository
    {
        get { return new AddressRepository(this); }
    }

    public IColorRepository ColorRepository
    {
        get { return new ColorRepository(this); }
    }

    public IHideOrderRepository HideOrderReposiotory
    {
        get { return new HideOrderRepository(this); }
    }

    public ISampleOrderRepository SampleOrderRepository
    {
        get { return new SampleOrderRepository(this); }
    }

    public ITaxonomyRepository TaxonomyRepository
    {
        get { return new TaxonomyRepository(this); }
    }

    PhoeniceContext IUnitOfWork<PhoeniceContext>.Context
    {
        get { return _context; }
    }
}
公共类PhoeniceUnitOfWork:iPhoneNiceUnitOfWork
{
私有只读PhoeniceContext\u上下文;
public PhoeniceUnitOfWork():base()
{
_上下文=新的PhoeniceContext();
}
//留作测试之用
公共PhoeniceUnitOfWork(PhoeniceContext上下文)
{
_上下文=上下文;
}
公共整数保存()
{
返回_context.SaveChanges();
}
公共空间处置()
{
_context.Dispose();
}
公共存储库地址存储库
{
获取{returnnewaddressrepository(this);}
}
公共图像存储库
{
获取{returnnewcolorrepository(this);}
}
公共信息隐藏
{
获取{returnnewhideOrderepository(this);}
}
公共ISampleOrderRepository示例OrderRepository
{
获取{返回新的SampleOrderRepository(this);}
}
公共Itaxonomy存储库分类存储库
{
获取{returnnewtaxonomyrepository(this);}
}
PhoeniceContext IUnitOfWork.Context
{
获取{return\u context;}
}
}
以及我使用的上下文

public class PhoeniceContext : EntityContext
{
    // You can add custom code to this file. Changes will not be overwritten.
    // 
    // If you want Entity Framework to drop and regenerate your database
    // automatically whenever you change your model schema, add the following
    // code to the Application_Start method in your Global.asax file.
    // Note: this will destroy and re-create your database with every model change.
    // 
    // System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<Phoenice.EntityFramework.Models.PhoeniceContext>());

    public PhoeniceContext()
        : base("Phoenice")
    {
        Database.SetInitializer<PhoeniceContext>(new DropCreateIfChangeInitializer());
        //Database.SetInitializer<PhoeniceContext>(new DropCreateDatabaseAlways());
    }

    public DbSet<Address> Addresses { get; set; }
    public DbSet<SampleOrder> SampleOrders { get; set; }
    public DbSet<HideOrder> HideOrders { get; set; }
    public DbSet<OrderItem> OrderItems { get; set; }
    public DbSet<Color> Colors { get; set; }
    public DbSet<Taxonomy> Taxonomies { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //There is OnModelCreating already overwritten in IdentityDbContext 
        //with all details required for ASP.NET identity
        base.OnModelCreating(modelBuilder);

        //solution for this mapping: http://stackoverflow.com/questions/11632951/primary-key-violation-inheritance-using-ef-code-first
        modelBuilder.Entity<SampleOrder>()
            .HasKey(x => x.OrderId)
            .Map(m =>
            {
                //Requires EF 6.1
                m.MapInheritedProperties();
                m.ToTable("SampleOrders");
            })
            .Property(x => x.OrderId)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        modelBuilder.Entity<HideOrder>().Map(m =>
        {
            //Requires EF 6.1
            m.MapInheritedProperties();
            m.ToTable("HideOrders");
        });
        modelBuilder.Entity<HideOrder>().HasKey(x => x.OrderId);
    }
}
公共类PhoeniceContext:EntityContext
{
//您可以将自定义代码添加到此文件。更改不会被覆盖。
// 
//如果希望实体框架删除并重新生成数据库
//无论何时更改模型架构,都会自动添加以下内容
//应用程序启动方法的代码
List<OrderItem> orderItems = new List<OrderItem>();
    foreach (var oi in fullOrder.Order)
    {
        //detach oi
         //attach oi
        var color = _colorRepo.Find(oi.ColorId);
        var item = new OrderItem
        {
            Quantity = oi.Quantity,
            Color = color
        };
        orderItems.Add(item);
    }
_colorRepo.Find(oi.ColorId);
   _sampleOrderRepo.InserGraph(order);
var color = new Color()
{
     id = oi.ColorId

}