【问题标题】:Clone an object (EF entity) in C#在 C# 中克隆一个对象(EF 实体)
【发布时间】:2020-03-08 09:46:30
【问题描述】:

使用 C# 8 e ASP.NET Core 我有以下内容:

  Context context = new Context();

  Post post1 = new Post {
    Enabled = true,
    Title = "Some title"
  };

  Post post2 = post1;
  post2.Enabled = false;

  context.Posts.Add(post1);
  context.Posts.Add(post2);

context,这是一个 EF DBContext,我只收到一个帖子 (post2);

也许我错了,但我认为我应该复制/克隆 post1 来定义 post2。

我说的对吗?如何做到这一点?

【问题讨论】:

  • 您只创建了一个帖子。你还有什么期待?是的,您可以根据需要创建第二个,或克隆第一个。 post2 = new Post { Title = post1.Title };
  • 将其标记为副本似乎有点激进。另外,我在下面的完整答案为您提供了一个 EF 模型克隆,它是已被链接为重复的已接受答案代码的 1/100

标签: c# asp.net-core entity-framework-core asp.net-core-3.0 c#-8.0


【解决方案1】:

因为这条线:

Post post2 = post1;

post1post2 是同一个对象,EF 会将它们视为同一个对象。

你应该有一些克隆来创建一个全新的帖子,比如:

Post post2 = new Post()
{
   Title = post1.Title,
   Enabled = false;
};

可能的其他克隆方式无需设置单个属性(请参阅this answer 了解更多详细信息)

Post post2 = (Post) context.Entry(post1).CurrentValues.ToObject();

【讨论】:

  • 当然,但我想避免这种情况,因为 Post 不仅有我提到的两个属性,还有很多属性。所以我一直在寻找一种更好的方法来克隆它。
  • 查看我的编辑,我在 SO 上找到了另一个答案,其中包含使用 EF 模型进行深层复制的代码
【解决方案2】:

因为classReferenceType,所以你只能得到一个post2Enabled 作为false,实际上是post1,它们在你的代码中是一样的,post1 === post2

我相信您的真实课程包含比示例更多的属性。 所以如果你想要一个简单的Clone,你可以使用var post2 = (Post)post1.Clone();,但通常我们在复杂的对象中使用deep clone,你可以关注这个帖子: Deep cloning objects

【讨论】:

    猜你喜欢
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    • 2018-11-27
    • 1970-01-01
    • 2017-11-17
    相关资源
    最近更新 更多