如何将现有实体附加到通用的实体框架上下文中?

时间:2017-10-09 13:41:04

标签: c# entity-framework generics entity-framework-6

我想在实体框架6中加载带有AsNoTracking和LazyLoadingEnabled = false的实体。在某些特殊情况下,我想显式重新加载一些集合。如何显式加载分离实体的集合?

我正在寻找一个通用选项,将现有实体附加到上下文。

我的电话如下:

var myCar = await this.myCarRepositoryAccessor.GetById(this.UnitOfWork, 1).ConfigureAwait(false);
this.UnitOfWork.LoadCollection(myCar, e => e.Driver);

DataRepository中的GetById如下所示:

public Task<TEntity> GetById(int id)
{
    return id == 0
        ? Task.FromResult(default(TEntity))
        : this.Context.InternalSet<TEntity>().AsNoTracking()?.SingleOrDefaultAsync(p => p.Id == id);
}

UnitOfWork中的LoadCollection如下所示:

public void LoadCollection<TEntity, TElement>(TEntity entity, Expression<Func<TEntity, ICollection<TElement>>> navigationProperty) where TEntity : class, IEntity where TElement : class
{
    //this.context.Entry(entity).State = EntityState.Unchanged
    this.context.Entry(entity).Collection(navigationProperty).Load();
}

我尝试将实体状态设置为Unchanged,但我收到此错误消息:

  

附加“MyCar”类型的实体失败,因为同一类型的另一个实体已具有相同的主键值。如果图中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新的并且尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图表,然后根据需要将非新实体的状态设置为“未更改”或“已修改”。

1 个答案:

答案 0 :(得分:1)

我想这是因为AsNoTracking(),显式加载不起作用。

如果你想使用显式加载,你应该从你的getbyid方法中删除它。

另请注意,您可以将字符串与集合一起使用,因此您可以简单地使用字符串或字符串列表,而不是附加func,以防您需要加载多个导航。

很高兴知道,对于集合,您使用集合,对于单个实体导航,您应该使用参考

你可以做的最好的事情是在你的getbyid字符串列表中添加另一个param,并包括该列表中的所有字符串,因为include也接受字符串。