我在WPF应用程序中使用EF 6。我正在尝试构建一个抽象数据库特定代码的分层架构 从应用程序的其余部分。我采用DbSet<> .Local的实例数据绑定到我的UI控件的方法,以减轻负担 变更跟踪我保持上下文很长一段时间,即从打开一个新数据库到这个时间 它已关闭。根据我的研究,基于Microsoft的这篇文章,似乎这是基于4.1之后的EF版本的推荐方法 (http://msdn.microsoft.com/en-US/data/jj574514)即使它似乎不是一个受欢迎的选择。
但是,当我尝试做最简单的事情时,我会收到异常。目前,我已将其缩小到我尝试清除时发生的这一异常 来自DbSet.Local的所有实体。请参阅下面的代码中的MVPModel.Clear()中的代码行。基本上,它试图执行:DbSet.Local.Clear()。
我注定会遇到这种方法的麻烦吗?
我使用这个类绑定到MVP风格的架构中的UI。
public class MVPModel
{
public ObservableCollection<ConcreteModel> Models { get; set; }
public void Attach(Database db)
{
this.Models = db.GetRepository<ConcreteModel>();
}
public void Detach()
{
this.Models = null;
}
public void Clear()
{
// Throwns an InvalidOperationException with the message
// The property 'Id' is part of the object's key information and cannot be modified.
Models.Clear();
}
}
public class ModelBase : INotifyPropertyChanged
{
private Int32 _id;
[Key]
public Int32 Id
{
get
{
return this._id;
}
set
{
if (_id != value)
{
_id = value;
OnPropertyChanged("Id");
}
}
}
}
public class ConcreteModel : ModelBase
{
// ...
}
public class MyDbContext : DbContext
{
public DbSet<ConcreteModel> Models { get; set; }
}
我在EF数据库上下文周围创建了一个包装器,它释放了与DbContext相关联的非托管资源。
public class Database : IDisposable
{
private MyDbContext _dbContext;
/// <summary>
/// Get a reference to a collection
/// </summary>
/// <typeparam name="T">ObservableCollection generic template type</typeparam>
/// <returns>An observable collection bound to the database repository</returns>
public ObservableCollection<T> GetRepository<T>()
{
ObservableCollection<T> retValue = null;
var dbSet = this._dbContext.Set(typeof(T));
if (dbSet != null)
{
try
{
// Force a query against the database to load the data. Otherwise, .Local will always be
// empty. This is similar to called DbSet<T>.ToList() but it saves the overhead of creating
// a throw away instance of List<>.
dbSet.Load();
}
catch (Exception ex)
{
// Load will fail if the database hasn't been created yet, e.g. File|New
ex.Post();
}
retValue = dbSet.Local as ObservableCollection<T>;
Debug.Assert(retValue != null);
}
return retValue;
}
// ...
}
这是例外的副本:
发生了System.InvalidOperationException 的HResult = -2146233079 消息=属性&#39; Id&#39;是对象的关键信息的一部分,不能修改。 来源=的EntityFramework 堆栈跟踪: 在System.Data.Entity.Core.Objects.EntityEntry.DetectChangesInProperty(Int32 ordinal,Boolean detectOnlyComplexProperties,Boolean detectOnly) InnerException:
来自我的调用堆栈的更多内容:
System.Data.Entity.Core.Objects.EntityEntry.DetectChangesInProperty(int ordinal = 0, bool detectOnlyComplexProperties = false, bool detectOnly = false)
System.Data.Entity.Core.Objects.EntityEntry.DetectChangesInProperties(bool detectOnlyComplexProperties = false)
System.Data.Entity.Core.Objects.ObjectStateManager.DetectChangesInScalarAndComplexProperties(System.Collections.Generic.IList<System.Data.Entity.Core.Objects.EntityEntry> entries = Count = 20)
System.Data.Entity.Core.Objects.ObjectStateManager.DetectChanges()
System.Data.Entity.Core.Objects.ObjectContext.DetectChanges()
System.Data.Entity.Internal.InternalContext.DetectChanges(bool force = false)
...