我在保存与Section有1-M关系的对象(FeatureType)时遇到一些问题。
public class FeatureType
{
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey("SectionId")]
public Section Section { get; set; }
public virtual List<ItemType> ItemTypes { set; get; }
}
public class Section
{
public int Id { get; set; }
public string Name { get; set; }
public int Order { get; set; }
public virtual List<FeatureType> Features { get; set; }
}
如果ItemTypes是新的,我没有问题并且插入正确完成。
但是如果我想添加一些现有的ItemTypes即可获得此错误:
实体对象不能被多个实例引用 IEntityChangeTracker。
我一直在阅读这个问题,但我还没有找到解决问题的方法,这可能是因为它设计了我的应用程序。
从我的viewModel到我的Model,我正在获取部分ID,并从我的SectionRepository获取部分Object,如下所示:
private Section GetSection()
{
var section = _sectionRepository.GetSection(SectionId);
return section;
}
这就是给我带来问题的原因,因为现在已经由具有自己的上下文的SectionRepository跟踪了该部分。
我该如何解决这个问题?我尝试使用现有ID创建一个新部分,但它只是创建了一个空对象。
private Section GetSection()
{
var section = new Section{Id=SectionId};
return section;
}
更新
要保存我的实体,我只需使用:
_repository.Create(featureType.ToModel());
public FeatureType ToModel()
{
var ft = new FeatureType
{
Name = Name,
ControlType = (ControlType)ControlType,
Order = Order,
Required = Required,
RequiredText = RequiredText,
ItemTypes = GetItemTypes().ToList(),
Section = GetSection(),
};
return ft;
}
更新2:这就是我拥有我的存储库的方式,我不想管理我的控制器中的任何EF,而是使用某种存储库或服务。
public class EFBaseRepository
{
protected MyContext Db = new MyContext();
public void Dispose(bool disposing)
{
Db.Dispose();
}
}
public class EFFeatureTypeRepository : EFBaseRepository, IFeatureTypeRepository
{
public IQueryable<FeatureType> GetFeatureTypes
{
get { return Db.FeatureTypes.Include("Section").Include("ItemTypes"); }
}
public Message Create(FeatureType feature)
{
try
{
Db.FeatureTypes.Add(feature);
Db.SaveChanges();
return new Message();
}
catch (Exception e)
{
throw;
// return new Message(e, string.Format("Error Creating {0}", feature.GetType()));
}
}
//..Other Methods
}
答案 0 :(得分:1)
你说SectionRepository
有自己的背景。这会给你带来麻烦。存储库应该共享上下文。上下文是工作单元和存储库模式的组合。您需要将两种模式分开:
How to migrate towards unit-of-work and repository pattern
修改强>
您可以通过实施自己的工作单元模式来避免在控制器中使用DbContext
。
public interface IUnitOfWork : IDisposable
{
ISectionRepository SectionRepository {get;}
//etc
int Save();
}
然后在你的控制器中:
public ActionResult Create(FeatureTypeCreate featureType)
{
_Uow.SectionRepository.Create(featureType.ToModel());
_Uow.Save(); //Saving is the responsibility of the Unit Of Work
//not the Repository
}
更多参考资料:
Implementing the Repository and Unit of Work
答案 1 :(得分:0)
简单地说,您获得的错误意味着实体是从DbContext
的不同实例返回的,而不是现在尝试保存的实例。确保您没有在存储库中使用两个不同的using
,并且您的存储库总是在每个实例中使用相同的DbContext
。