C# MVC中的模型复制#

C# MVC中的模型复制#,c#,asp.net-mvc,C#,Asp.net Mvc,我需要将模型映射到相应的数据表,并且每次更新模型/表时,我都需要将更改映射到存档表以供历史参考。例如— [Table("A")] public class A { [Key] public int A_Id { get; set; } [Display(Name = "First Name")] public string FirstName { get; set; } [Display(Name = "Last Name"

我需要将模型映射到相应的数据表,并且每次更新模型/表时,我都需要将更改映射到存档表以供历史参考。例如—

[Table("A")]
public class A
{
    [Key]       
    public int A_Id { get; set; }       

    [Display(Name = "First Name")]
    public string FirstName { get; set; }

    [Display(Name = "Last Name")]
    public string LastName { get; set; }
}

[Table("A_History")]
public class A_History
{
    [Key]   
    public int A_History_Id { get; set; }       

    public int A_Id { get; set; }       

    [Display(Name = "First Name")]
    public string FirstName { get; set; }

    [Display(Name = "Last Name")]
    public string LastName { get; set; }
}

所以每次修改表A时,我都需要向一个_历史添加一个条目,其中包含新数据或原始数据的精确副本。有没有一种通用的方法可以做到这一点,比如我可以将一个字符串作为模型名传递给一个方法或类,并且该方法可以自动循环遍历模型类的所有属性,并将它们映射到另一个要通过匹配名称添加的类?

下面使用了反射,所以要注意性能。如果性能是一个非常重要的方面,那么最好一个一个地映射属性,但是如果您正在研究通用实现,您可以尝试下面的代码片段

// object instances
A sourceInstance = new A();
A_History destInstance = new A_History();
MapSourceValuesToDestination(sourceInstance, destInstance);

private void MapSourceValuesToDestination(object sourceObject, object destinationObject)
{
    //get all properties
    PropertyInfo[] sourceProperties = typeof (sourceObject).GetProperties();
    PropertyInfo[] destinationProperties = typeof (destinationObject).GetProperties();

    // foreach in source
    foreach (PropertyInfo property in sourceProperties)
    {
        if (property != null)
        {
            string propertyName = property.Name;
            if (!string.IsNullOrEmpty(propertyName))
            {
                // get destination property matched by name
                PropertyInfo matchingProperty = destinationProperties.FirstOrDefault(x => x.Name.Equals(propertyName, StringComparison.InvariantCultureIgnoreCase));    
                if (matchingProperty != null)
                {
                    // get source value
                    object sourceValue = property.GetValue(sourceInstance);
                    if (sourceValue != null)
                    {
                        // set source value to destination
                        matchingProperty.SetValue(destInstance, sourceValue);
                    }
                }
            }
        }
    }
}

下面使用反射,所以要注意性能。如果性能是一个非常重要的方面,那么最好一个一个地映射属性,但是如果您正在研究通用实现,您可以尝试下面的代码片段

// object instances
A sourceInstance = new A();
A_History destInstance = new A_History();
MapSourceValuesToDestination(sourceInstance, destInstance);

private void MapSourceValuesToDestination(object sourceObject, object destinationObject)
{
    //get all properties
    PropertyInfo[] sourceProperties = typeof (sourceObject).GetProperties();
    PropertyInfo[] destinationProperties = typeof (destinationObject).GetProperties();

    // foreach in source
    foreach (PropertyInfo property in sourceProperties)
    {
        if (property != null)
        {
            string propertyName = property.Name;
            if (!string.IsNullOrEmpty(propertyName))
            {
                // get destination property matched by name
                PropertyInfo matchingProperty = destinationProperties.FirstOrDefault(x => x.Name.Equals(propertyName, StringComparison.InvariantCultureIgnoreCase));    
                if (matchingProperty != null)
                {
                    // get source value
                    object sourceValue = property.GetValue(sourceInstance);
                    if (sourceValue != null)
                    {
                        // set source value to destination
                        matchingProperty.SetValue(destInstance, sourceValue);
                    }
                }
            }
        }
    }
}

如果您的历史模型与保存历史的模型具有相同的属性,则可以执行以下操作

  • 添加
    Newtonsoft.Json
    nuget包并执行

  • 添加如下所示的代码

    A model = new A();
    //.....
    // add data to the model
    var json = JsonConvert.SerializeObject(model);
    A_History historyModel = JsonConvert.DeserializeObject<A_History>(json);
    
    A模型=新的A();
    //.....
    //向模型中添加数据
    var json=JsonConvert.serialized对象(模型);
    A_History History model=JsonConvert.DeserializeObject(json);
    
  • 现在,您的历史模型将填充和模型相同的所有属性


  • 如果您的历史模型与保存历史的模型具有相同的属性,则可以执行以下操作

  • 添加
    Newtonsoft.Json
    nuget包并执行

  • 添加如下所示的代码

    A model = new A();
    //.....
    // add data to the model
    var json = JsonConvert.SerializeObject(model);
    A_History historyModel = JsonConvert.DeserializeObject<A_History>(json);
    
    A模型=新的A();
    //.....
    //向模型中添加数据
    var json=JsonConvert.serialized对象(模型);
    A_History History model=JsonConvert.DeserializeObject(json);
    
  • 现在,您的历史模型将填充和模型相同的所有属性


  • 听起来您正在寻找类似Automapper的东西…将历史数据存储在不同的数据库中可能是个好主意我以前没有使用过Automapper,但从我读到的来看,这不是用于将ViewModel映射到模型吗?对于不同数据库中的历史数据,这有什么好处?您是否担心数据的大小会变得非常大?速度?听起来你在寻找类似Automapper的东西…将历史数据存储在不同的数据库中可能是个好主意我以前没有使用过Automapper,但从我读到的来看,这不是用于将ViewModel映射到模型吗?对于不同数据库中的历史数据,这有什么好处?您是否担心数据的大小会变得非常大?速度?谢谢你。当我有机会的时候,我必须尝试一下。是的,我正在寻找一个通用的实现,因为每个更新的数据表都需要相应历史表的更新/归档。我还没有尝试过这种方法。我已经试过自动映射器,它工作得很好。我将在下周尝试这种方法。我将在下周发布一个更新,一旦我尝试一下。我想知道它是否也能起作用。谢谢你的帮助,谢谢你。当我有机会的时候,我必须尝试一下。是的,我正在寻找一个通用的实现,因为每个更新的数据表都需要相应历史表的更新/归档。我还没有尝试过这种方法。我已经试过自动映射器,它工作得很好。我将在下周尝试这种方法。我将在下周发布一个更新,一旦我尝试一下。我想知道它是否也能起作用。谢谢你的帮助。