Andrew Andrew - 1 year ago 74
C# Question

Save object with one-many relationship

I have a

model and I want to update the
record and save a list of phone numbers all at once. There is a 1-* relationship.

My ViewModel looks like:

public class CompanyRegisterViewModel
public int CompanyId { get; set; }

public int CompanyTypeId { get; set; }

public IEnumerable<SelectListItem> CompanyTypes { get; set; }

[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(ValidationStringResource))]
[MaxLength(250, ErrorMessageResourceName = "MaximumLength", ErrorMessageResourceType = typeof(ValidationStringResource))]
public string LicensedCompanyName { get; set; }

public List<Phone> Phones { get; set; }

In my
Save(Company company)
method, if I call:


Will this save a new company record and save the
List<Phone> Phones
or do I need a transaction and call
again to save the
. I also need to set
for each
record. Should I loop through the
records prior to saving and update each record in a
loop? I want this set automatically in the backend, not in the UI.

Answer Source

If you want to automatically set properties like Modified and ModifiedBy everytime you call SaveChanges or SaveChangesAsync, you have to do 2 things.

Create a base interface, from which all your entities inherit from

public interface IEntityRoot
    public DateTime Created { get; set; }
    public string CreatedBy { get; set; }
    public DateTime Modified { get; set; }
    public string ModifiedBy { get; set; }

Inherit all your entites from this interface:

  public class Company : IEntityRoot { ... }

With this, all entities which inherit from this interface will have the properties Created & CreatedBy. The last step is to create a small method, which is called every time you save your changes and automatically sets the current date and user.

public class ApplicationContext : DbContext
    /* ... */
    public override int SaveChanges()
        return base.SaveChanges();

    public override async Task<int> SaveChangesAsync()
        return await base.SaveChangesAsync();

    private void TrackModifiedDates()
        var entities = ChangeTracker.Entries()
                                    .Where(x => x.Entity is IEntityRoot && (x.State == EntityState.Added) || (x.State == EntityState.Modified));
        //if anonymous access is possible, do a null check here.
        var userName = HttpContext.Current.User.Identity.Name

        foreach (var entity in entities)
            if(entity.State == EntityState.Added) 
                ((IEntityRoot)entity.Entity).Created = DateTime.UtcNow;
                ((IEntityRoot)entity.Entity).CreatedBy = userName;

            ((IEntityRoot)entity.Entity).Modified = DateTime.UtcNow;
            ((IEntityRoot)entity.Entity).ModifiedBy = userName;
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download