my application has 2 classes: PaymentMethod
& Currency
(Currency
is property of PaymentMethod
). When my app does upda
This issue is because of foreign key relation in not defined in PaymentMethod class. That need to be specify so specific column will be used to update and in case currency is new then that will be inserted and same code will be saved against currencycode.
public class PaymentMethod : BaseEntity
{
public enum MethodTypeEnum
{
Creditcard,
Virtualcard,
Wallet
};
public MethodTypeEnum MethodType { get; set; }
public int VendorId { get; set; }
public virtual Address BillingAddress { get; set; }
public string CurrencyCode {get;set;} //Replace with actual column name
[ForeignKey("CurrencyCode ")]
public virtual Currency Currency { get; set; }
}
Setting an entity's state (other than Added
) only affects the entity's scalar properties, not its navigation properties, its associations.
So you have three options:
Attach the currency to the context. In your Edit
method:
Context.Entry(entityToUpdate).State = EntityState.Modified;
Context.Entry(entityToUpdate.Currency).State = EntityState.Unchanged;
Now EF knows the Currency
that is assigned to PaymentMethod
, so it knows the association changed, and it will update the foreign key in the database.
But I don't think this is going to work for you just like that. From your problem statement I understand that currencyRepo
and paymentMethodRepository
don't share the same context, otherwise you wouldn't have had the problem in the first place (the currency would already be attached). You can't attach an entity to two contexts, so either currencyRepo
's context should be disposed at that point, or you should detach the currency from it first. Pretty laborious.
Let currencyRepo
and paymentMethodRepository
(and all repositories for that matter) share the same context instance within one unit of work. This is recommended anyway, not only to solve this problem.
Don't set the Currency
property, but add a primitive foreign key property PaymentMethod.CurrencyId
and modify that property if the currency changes. This is a scalar property, so it will respond to setting EntityState.Modified
.
DbSet.Attach
is not recursive. You need to attach all the entities involed:
public override void Edit(MwbePaymentMethod entityToUpdate)
{
DbSet.Attach(entityToUpdate);
Context.Entry(entityToUpdate).State = EntityState.Modified;
if(entityToUpdate.BillingAddress != null)
{
DbSet.Attach(entityToUpdate.BillingAddress);
Context.Entry(entityToUpdate.BillingAddress).State = EntityState.Modified;
}
if(entityToUpdate.Currency != null)
{
DbSet.Attach(entityToUpdate.Currency);
Context.Entry(entityToUpdate.Currency).State = EntityState.Modified;
}
//manual update of properties
//Context.Entry(entityToUpdate.BillingAddress).State = EntityState.Modified;
//Context.Entry(entityToUpdate.Currency).State = EntityState.Unchanged;
}