Tim*_*ann 9 c# entity-framework dbcontext
我有一个与我无关的实体dbcontext.我想改变这一点.但是,已经有另一个相同实体的实例附加到dbcontext.如果我只是添加我的新实体,我会收到一个错误,即已经附加了具有相同主键的实体.
我尝试了多种不同的删除旧实体的变体,dbcontext没有任何成功.如何用新的实例替换旧实例?
注意:我不想复制值,我想将我的新实体的这个实例附加到dbcontext.
var entity = new MyEntity { Id = 1 };
var logicalDuplicate = dbcontext.Set<MyEntity >().Local
.FirstOrDefault(e => e.Equals(entity ));
if (logicalDuplicate != null)
{
// remove logicalDuplicate from dbcontext
}
dbcontext.MyEntity.Attach(entity);
Run Code Online (Sandbox Code Playgroud)
澄清:我已经覆盖Equals检查Id而不是参考.
试试这个:
if (logicalDuplicate != null)
{
dbcontext.Entry(logicalDuplicate).State = EntityState.Detached;
dbcontext.MyEntity.Attach(entity);
dbcontext.Entry(entity).State = EntityState.Modified;
}
else
{
dbcontext.MyEntity.Add(entity);
}
Run Code Online (Sandbox Code Playgroud)
我对此进行了调查,并希望与我的结果分享.我使用反射作为获取实体属性名称的简短方法.但是,正如@Florian Haider所提到的,它可以在没有反思的情况下得到它.你可以使用 答案和这个.
// Found loaded related entries that can be detached later.
private HashSet<DbEntityEntry> relatedEntries;
private DbContext context;
private List<string> GetPropertiesNames(object classObject)
{
// TODO Use cache for that.
// From question https://stackoverflow.com/questions/5851274/how-to-get-all-names-of-properties-in-an-entity
var properties = classObject.GetType().GetProperties(BindingFlags.DeclaredOnly |
BindingFlags.Public |
BindingFlags.Instance);
return properties.Select(t => t.Name).ToList();
}
private void GetRelatedEntriesStart(DbEntityEntry startEntry)
{
relatedEntries = new HashSet<DbEntityEntry>();
// To not process start entry twice.
relatedEntries.Add(startEntry);
GetRelatedEntries(startEntry);
}
private void GetRelatedEntries(DbEntityEntry entry)
{
IEnumerable<string> propertyNames = GetPropertiesNames(entry.Entity);
foreach (string propertyName in propertyNames)
{
DbMemberEntry dbMemberEntry = entry.Member(propertyName);
DbReferenceEntry dbReferenceEntry = dbMemberEntry as DbReferenceEntry;
if (dbReferenceEntry != null)
{
if (!dbReferenceEntry.IsLoaded)
{
continue;
}
DbEntityEntry refEntry = context.Entry(dbReferenceEntry.CurrentValue);
CheckReferenceEntry(refEntry);
}
else
{
DbCollectionEntry dbCollectionEntry = dbMemberEntry as DbCollectionEntry;
if (dbCollectionEntry != null && dbCollectionEntry.IsLoaded)
{
foreach (object entity in (ICollection)dbCollectionEntry.CurrentValue)
{
DbEntityEntry refEntry = context.Entry(entity);
CheckReferenceEntry(refEntry);
}
}
}
}
}
private void CheckReferenceEntry(DbEntityEntry refEntry)
{
// Add refEntry.State check here for your need.
if (!relatedEntries.Contains(refEntry))
{
relatedEntries.Add(refEntry);
GetRelatedEntries(refEntry);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3352 次 |
| 最近记录: |