PawelGerr / Thinktecture.EntityFrameworkCore

These libraries extend Entity Framework Core by a few features to make it easier to work with EF and for easier integration testing or to get more performance in some special cases.
https://dev.azure.com/pawelgerr/Thinktecture.EntityFrameworkCore
BSD 3-Clause "New" or "Revised" License
61 stars 17 forks source link

`IEntityPropertiesProvider.Exclude<T>` does not exclude properties for derived types #37

Closed DavidAllardyce closed 1 year ago

DavidAllardyce commented 1 year ago

I have an entity which derives from another entity and when I attempt to do a Bulk Operation I cannot exclude properties because

 IEntityPropertiesProvider.Exclude<DerivedClass>(entity => new { entity.CreateDate });

does not remove the desired property from the property set.

I can replicate the issue with the following test using the test data:

   var entityType = ActDbContext.Model.GetEntityType(typeof(TestEntityWithBaseClass));

   var optionalProperty = entityType.FindProperty(nameof(TestEntityWithBaseClass.Optional)) ?? throw new Exception("Property must not be null");
   var otherKeyProperty = entityType.FindProperty(nameof(TestEntityWithBaseClass.OtherKey)) ?? throw new Exception("Property must not be null");

    var propertiesProvider = IEntityPropertiesProvider.Exclude<TestEntityWithBaseClass>(entity => new
    {
        entity.Optional,
        entity.OtherKey
    });

    var properties = propertiesProvider.GetPropertiesForTempTable(entityType);
    properties.Should().HaveCount(entityType.GetProperties().Count() - 2);
    properties.Should().NotContain(optionalProperty);
    properties.Should().NotContain(otherKeyProperty);

It appears the issue is with the Filter method within ExcludingEntityPropertiesProvider. Specifically, _members.All(m => m != p.Property.PropertyInfo && m != p.Property.FieldInfo) does not match for the derived type.

If I change the MemberInfo comparison to something like this then my code works and all the tests pass:

 member.MetadataToken == other.MetadataToken &&
 member.Module.Equals(other.Module) &&
 Equals(member.DeclaringType, other.DeclaringType)

(Okay, not all of the tests pass. The IfExists and IfNotExists fail, but they were failing before I made any changes)

I can submit a PR with my changes if you want to take a look.

PawelGerr commented 1 year ago

Thank your support! Please check out the version 4.5.1/7.0.0-beta05.

DavidAllardyce commented 1 year ago

Excellent! That solved my problem. Thanks!