Roberto
Roberto

Reputation: 303

EF Core. Update Entity without update navigation properties

I am trying to update an Entity EF Core record like this:

public class Customer
{
    public int Id { get; set; }
    public int Name { get; set; }
    ...
    public int CountryId { get; set; }
    public virtual Country Country { get; set; }

    public int ZoneId { get; set; }
    public virtual Zone Zone { get; set; }

    public ICollection<Service> Services { get; set; }

    public virtual ICollection<Invoice> Invoices { get; set; }
}

When I call Context.Update() or Context.Add(), also update Zone and Country entities. I don't want that the virtual properties update. I am trying, with reflection, get the virtual properties for indicate that Entry(virtualProperty).State = EntityState.Detached, but I can not. This is the code that I am trying.

Type typeOfTEntity = typeof(TEntity);
foreach (var property in typeOfTEntity.GetProperties())
{
    if (property.GetGetMethod().IsVirtual)
    {
        foreach (var member in context.Context.Entry(CurrentItem).Members)
        {
            if (member.Metadata.Name == property.Name)
            {
                context.Context.Entry(member).State = EntityState.Detached;
            }
        }
    }
}

I get the error: "The entity type 'ReferenceEntry' was not found. Ensure that the entity type has been added to the model." I use TEntity because I use more entities in a generic Class and use the same method to Update or Add. Thanks in advance.

Edit: If I use the entity (CurrentItem) like non generic type: (CurrentItem is now Customer, instead of TEntity)

context.Context.Entry(CurrentItem.Country).State = EntityState.Detached;
context.Context.SaveChanges();

Now works well. But I need to use TEntity.

Upvotes: 0

Views: 2662

Answers (2)

Roberto
Roberto

Reputation: 303

I managed to solve the problem. Instead of inserting the property in the Entry, the value of the property had to be inserted.

using (var context = new OpenContext<TContext>(connectionString))
{
    var repository = context.UnitOfWork.GetRepository<TEntity, TKey>();
    repository.Update(CurrentItem);

    // Get the type of TEntity
    Type typeOfTEntity = typeof(TEntity);
    foreach (var property in typeOfTEntity.GetProperties())
    {
        // Check the properties that are virtual and not are HashSet
        if (property.GetGetMethod().IsVirtual && property.PropertyType.GenericTypeArguments.Count() == 0)
        {
            object value = property.GetValue(CurrentItem);
            // Check that value is not null and value type is an Entity
            if (value != null && value.GetType().IsSubclassOf(typeof(Entity<int>)))
            {
                // Set the value that I don't want to change
                context.Context.Entry(value).State = EntityState.Detached;
            }
        }
    }
    context.UnitOfWork.SaveChanges();
}

Thanks for the help.

Upvotes: 1

Fabien Dezautez
Fabien Dezautez

Reputation: 129

If you don't want to Update "subentities", you should not Include them when you get the Customer you wan't to update.

Upvotes: 0

Related Questions