简体   繁体   中英

Entity Framework updating entry with related entries only updates main entry

Situation: my Main class looks like this:

class Main 
{
    public int Id { get; set; }
    public Customer Customer { get; set; }
}

My Customer class looks like this:

class Customer 
{
    public int Id { get; set; }
    public Address Address { get; set; }
    public EMail Email { get; set; }
    public Language Language { get; set; }
}

Problem: I was reading that it is better to use the context as short as possible with using syntax. So I take the main class out of the Database, let it change the props and will then update the main class.

The problem is that my related entries are all duplicates. I have tried several suggestions:

First approach:

private object InsertOrUpdate<T, TKey>(T entity, Func<T, TKey>  idExpression) where T : class
{       
  var existingEntity = LokaleContext.Set<T>().Find(idExpression(entity));
  if (existingEntity != null)
  {
    if (LokaleContext.Entry(existingEntity).State == EntityState.Detached)
    {
      LokaleContext.Set<T>().Attach(existingEntity);
    }
    else
    {
      LokaleContext.Entry(existingEntity).CurrentValues.SetValues(entity);
    }

    return existingEntity;
  }
  else
  {
    LokaleContext.Set<T>().Add(entity);
    return entity;
  }
}

I used this code to return the related entries and couple them back to the main class.

For example:

var customerFromDb = db.Set<Costumer>()
                       .Include(c => c.Address)
                       .Include(c => c.EMail)
                       .Include(c => c.Language)
                       .FirstOrDefault(c => c.Id == customerUsedLocal.Id);
customerUsedLocal.Customer.Address = InsertOrUpdate(customerFromDb.Customer.Address, a => a.Id);

I repeated this for Language and EMail classes.

After that I map the two classes;

MapObject(CustomerLoca, CustomerFromDb);
public object MapObject<T>(T entitySource, T entityDestination) where T : class
{
  var config = new MapperConfiguration(cfg => { cfg.CreateMap<T, T>(); });
  IMapper mapper = config.CreateMapper();
  return mapper.Map(entitySource, entityDestination);
}

and finally I set the state of the CustomerFromDb to modified.

But whatever I try to do, nothing is working, I tried all these links without any result :-(

OptimisticConcurrencyException when persisting related entry

Entity Framework not updating existing related entity

Finding updated entry with Entity Framework Timestamp using code first

Entity Framework Updating with Related Entity

Can someone please help me with this. Thanks a lot

I finally did it, I was confused about the examples given and muddle things. So here is my solution first I create a mapper configuration file

public class AutoMapperConfigurator:Profile
{

    public AutoMapperConfigurator()
    {
        CreateMap<Customer, Customer>()
            .ForMember(v=>v.Id, opt=>opt.Ignore())
            .ForMember(v=>v.Address,opt=>opt.Ignore())
            ;
    }
}

After that I go to the repository and do the following code:

//Get customer from db
var CustomerFromDb= LokaleContext.Set<Customer>().Include(c=>c.Address).FirstOrDefault(k => k.Id == Customer.Id);
//Couple the configfile to automapper
 var config = new MapperConfiguration(cfg => {cfg.AddProfile<AutoMapperConfigurator>();});
        IMapper mapper = config.CreateMapper();
//Map the two objects
        var CustomerforDb= mapper.Map(Customer, CustomerFromDb);
        //Get the address from the Db and couple it to the newly coupled      //entrie
        CustomerforDb.Address= LokaleContext.Set<Address>().SingleOrDefault(k=>k.Id==LichaamsBouw.Klant.Id);

        //save in db.
        LokaleContext.SaveChanges();

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