将上下文中的实体替换为同一实体的不同实例

蒂姆·波尔曼(Tim Pohlmann)

我有一个未与我的实体连接的实体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);

为了澄清:我已经覆盖Equals了检查Id而不是参考。

维塔利·斯莫里亚科夫(Vitaliy Smolyakov)

试试这个:

if (logicalDuplicate != null)
{
    dbcontext.Entry(logicalDuplicate).State = EntityState.Detached;
    dbcontext.MyEntity.Attach(entity);
    dbcontext.Entry(entity).State = EntityState.Modified;
}
else
{
    dbcontext.MyEntity.Add(entity);
}

如何获取相关条目

我对此进行了调查,并希望与我分享一下结果。我使用反射作为获取实体属性名称的捷径。但是有可能像@Florian Haider所说的那样不加思考地得到它。您可以使用answerthis

// 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);
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在同一上下文中添加对象时,实体框架不会返回代理

实体框架不会将数据库上下文中仍然存在的对象与从不同类引用的同一对象相关联

如何在不同的有界上下文中将学说实体分为更多的领域实体?

在实体框架核心上下文中命名Fk

替换上下文中字符的所有实例

如何验证所有集合是否在上下文中的所有实体中实例化

在边界上下文中为同一事物适应不同的标识符

实体框架核心上下文实例选项

实体框架6:在上下文中禁用跟踪时更新实体

实体框架核心-同一数据库中的2个上下文-未创建第二个上下文表

通过Spring Boot在同一上下文中创建的对象的两个不同的哈希码

什么是实体框架上下文中的复杂类型

如何使用linq-query获取不在上下文中的实体?

Entify Framework:重用添加到已处置上下文中的实体是否合法

DDD - 验证实体在其他有界上下文中的存在

从JPA / EJB3持久性上下文中分离实体

实体框架6能够在封闭上下文中引用嵌套对象

如何模拟实体框架并在模拟的上下文中获取新的插入值

实体框架上下文问题

实体框架对象上下文刷新

实体框架覆盖模型上下文

实体框架:无法加载上下文

无法为“MyTable”类型的实体调用成员“CurrentValues”,因为上下文中不存在该实体

实体框架:两个不同的上下文和一个数据库

实体框架从上下文重新加载实体

实体框架:根据上下文跟踪实体

实体框架 - 无法引用实体上下文

实体框架上下文自动创建新实体

将上下文差异转换为统一差异格式