【发布时间】:2020-02-23 01:58:49
【问题描述】:
我通过 asp.net core mvc 做项目。当我复制模型并更改其值时,原始模型的值也在发生变化,因为它通过引用复制了模型,因此数据中的值位置是相同的。 我需要一种方法来复制与原始模型无关的模型值。
【问题讨论】:
-
将每个属性复制或投影到一个新对象中或使用自动映射器或序列化,无论哪种方式都已被询问并搜索了很多
标签: c# entity-framework class oop
我通过 asp.net core mvc 做项目。当我复制模型并更改其值时,原始模型的值也在发生变化,因为它通过引用复制了模型,因此数据中的值位置是相同的。 我需要一种方法来复制与原始模型无关的模型值。
【问题讨论】:
标签: c# entity-framework class oop
您的问题可能有很多答案,具体取决于您要复制的对象的封装。我将假设您正在对低级实体对象而不是应该封装它的对象进行操作。如果这个假设不正确,并且它是封装实体操作的更高级别的对象,我会轻轻提醒您良好的编程实践:Martin Fowler - TellDontAsk。
对于答案,我将使用下面的类来说明:
public class Student
{
public int Id { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public DateTime EnrollmentDate { get; set; }
}
我假设正在发生的事情类似于以下内容:
Student john = new Student();
Student jane = john;
jane.FirstName = "Jane"; // now john.FirstName == "Jane"
您需要做的是将对象克隆到一个新的对象实例。有多种方法可以做到这一点。
选项#1:
// Create a new entity object manually assigning each value
// from the first object to the value in the new object.
var clonedStudent = new Student
{
Id = john.Id, // Copies value not reference
LastName = john.LastName, // string is immutable this OK
FirstName = john.FirstName, // string is immutable this OK
// DateTime is a struct I think so it should pass value
EnrollmentDate = john.EnrollmentDate // Verify my assumption
};
选项 #2:
// Make Student class partial and extend it with clone method.
// This is helpful for generated entities not using the code-first approach.
public partial class Student
{
public int Id { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public DateTime EnrollmentDate { get; set; }
}
public partial class Student
{
public Student Clone()
{
return new Student
{
Id = Id, // Copies value not reference
LastName = LastName, // string is immutable this OK
FirstName = FirstName, // string is immutable this OK
// DateTime is a struct I think so it should pass value
EnrollmentDate = EnrollmentDate, // Verify my assumption
};
}
}
要使用它,你会写:
Student clonedStudent = john.Clone();
选项 #3:您可以使用为您进行克隆的 NuGet 包。有各种各样的人这样做。一个快速的谷歌搜索为我找到了这个。 DeepCloner
如果您要将对象从一种类型复制到另一种类型,您可能需要使用AutoMapper。
注意:另外,根据您的问题,了解实体框架如何处理更改可能会很有用。
Tracking vs. No-Tracking Queries
希望对您有所帮助。
编码愉快!!!
【讨论】:
选项 1 使用 AutoMapper
选项 2 使用反射创建副本
public class PropertyCopier<TParent, TChild> where TParent : class
where TChild : class
{
public static void Copy(TParent parent, TChild child)
{
var parentProperties = parent.GetType().GetProperties();
var childProperties = child.GetType().GetProperties();
foreach (var parentProperty in parentProperties)
{
foreach (var childProperty in childProperties)
{
if (parentProperty.Name == childProperty.Name && parentProperty.PropertyType == childProperty.PropertyType)
{
childProperty.SetValue(child, parentProperty.GetValue(parent));
break;
}
}
}
}
}
【讨论】: