當屬性存在時,EntityEntry.Property()會拋出InvalidOperationException

.net-core asp.net-core c# entity-framework entity-framework-core

大家好我有以下課程:

public class EntityA
{
    public Guid Id { get; set; }
    public string Desc { get; set; }

    public EntityB EntityB { get; set; }
}

public class EntityB
{
    public Guid Id { get; set; }
    public Guid EntityAId { get; set; }
    public EntityA EntityA { get; set; }
}

我有以下運行時代碼:

var a1 = new EntityA {Desc = "a1"};
var a2 = new EntityA {Desc = "a2"};
dbx.EntityAs.Add(a1);
dbx.EntityAs.Add(a2);

var b1 = new EntityB { EntityAId = a1.Id };
dbx.EntityBs.Add(b1);
dbx.SaveChanges();
b1.EntityAId = a2.Id;
dbx.SaveChanges();

我在DbContext.SaveChanges()方法中修改了代碼,如下所示,嘗試查找實體中哪個屬性已更改及其前後值:

foreach (var entity in changedEntites)
{
var entityType = entity.Entity.GetType();

if (entity.State == EntityState.Modified)
{                  
    var properties = entityType.GetProperties();
    var props = new List<object>();
    foreach (var prop in properties)
    {
        if(entityType.GetProperty(prop.Name) == null)
            continue;
        var pp = entityType.GetProperty(prop.Name);
        if(pp.GetValue(entity.Entity) == null)
            continue;

        var p = entity.Property(prop.Name);
        if (p.IsModified)
            props.Add(new { f = prop.Name, o = p.OriginalValue, c = p.CurrentValue });
    }
}
}

有問題的代碼在這一行:

var p = entity.Property(prop.Name);

它拋出InvalidOperationException

The property 'EntityA' on entity type 'EntityB' could not be found.
Ensure that the property exists and has been included in the model.

我的問題是為什麼即使entityType.GetProperty(prop.Name)entityType.GetProperty(prop.Name).GetValue(entity.Entity)不為null, entity.Property()仍然無法找到屬性?

我可以圍繞var p = entity.Property(prop.Name);使用try-catch塊並忽略異常,但讓異常繼續投入審計場景並不是一件好事。它還會影響性能。

任何解決方法都非常感謝。謝謝

一般承認的答案

問題是,當您使用navigation屬性調用它時, Property方法僅支持原始屬性。

您可以使用通過EntityEntry.Metadata屬性訪問的ER Core元數據服務, EntityEntry.Metadata屬性返回IEntityType 。在你的情況下, FindProperty方法,雖然你應該首先使用GetProperties而不是反射:

if (entity.Metadata.FindProperty(prop.Name) == null)
    continue;

var p = entity.Property(prop.Name);
if (p.IsModified)
    props.Add(new { f = prop.Name, o = p.OriginalValue, c = p.CurrentValue });

熱門答案

這是因為entityEntityEntry 。您應該正確命名您的變量,以免混淆:

foreach (var entiry in changedEntries)
{
    var entity = entiry.Entity;
    var entityType = entity.GetType();

    if (entity.State == EntityState.Modified)
    {                  
        var properties = entityType.GetProperties();
        var props = new List<object>();
        foreach (var prop in properties)
        {
            if(entityType.GetProperty(prop.Name) == null)
                continue;
            var pp = entityType.GetProperty(prop.Name);
            if(pp.GetValue(entity) == null)
                continue;

            var p = entity.Property(prop.Name);
            if (p.IsModified)
                props.Add(new { f = prop.Name, o = p.OriginalValue, c = p.CurrentValue });
        }
    }
}


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow