简体   繁体   中英

MVC Model Duplication in C#

I have a need for models that are mapped to their corresponding data tables, and every time the models/tables are updated, I need to mapped the changes to the archived tables for historical references. For example -

[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; }
}

So every time Table A is modified, I need to add an entry to A_History with an exact copy of the new or original data. Is there a generic way to do this, such that I can pass in a string as the Model name to a method or class, and the method can automatically loop through all the properties of the Model class, and map them to another class to be added by matching the names?

Below uses reflection, so be careful of performance. If performance is a very important aspect then it might be better to actually map properties one by one, but if you're looking at generic implementation you could try the below snippet.

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

If your history model has the same properties as the model that holds the history of then you can do something like.

  1. Add the Newtonsoft.Json nuget package and do.

  2. Add the code shown bellow.

     A model = new A(); //..... // add data to the model var json = JsonConvert.SerializeObject(model); A_History historyModel = JsonConvert.DeserializeObject<A_History>(json); 
  3. Now your history model will have filled all the properties that are the same with the A model.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM