C# 实体框架ObjectStateEntry,获取关系的属性
我正在为实体框架开发一个变更分析器,还有一个小问题 我需要在关系(1-1,1-n,n-n)中获取父对象的属性(C# 实体框架ObjectStateEntry,获取关系的属性,c#,entity-framework,C#,Entity Framework,我正在为实体框架开发一个变更分析器,还有一个小问题 我需要在关系(1-1,1-n,n-n)中获取父对象的属性(PropertyInfo) 现在我可以看到关系、父项和相关条目,但我似乎无法获得对象的实际属性。我看到的问题是,关系知道密钥,它们是PKs和FKs,而不是最初负责关系的属性。在我现在的解决方案中,我使用相关实体的EntitySet名称,但这还不够好 下面是解析关系的代码。我省略了实体对象以及非关系分析部分。IHaveLogEntries接口将在需要分析的实体上实现 此外,此代码在DbCo
PropertyInfo
)
现在我可以看到关系、父项和相关条目,但我似乎无法获得对象的实际属性。我看到的问题是,关系知道密钥,它们是PKs和FKs,而不是最初负责关系的属性。在我现在的解决方案中,我使用相关实体的EntitySet名称,但这还不够好
下面是解析关系的代码。我省略了实体对象以及非关系分析部分。IHaveLogEntries
接口将在需要分析的实体上实现
此外,此代码在DbContext.SaveChanges()中运行
this.ChangeTracker.DetectChanges();
var objectContext=((IObjectContextAdapter)this).objectContext;
var entityEntries=objectContext.ObjectStateManager
.GetObjectStateEntries(EntityState.Unchanged | EntityState.Modified | EntityState.Added)
.ToList();
var relationEntries=objectContext.ObjectStateManager
.GetObjectStateEntries(EntityState.Added | EntityState.Deleted)
.ToList();
var q=从relationEntries中的relationEntry
从entityEntry到entityEntries
其中relationEntry.IsRelationshipForKey(entityEntry.EntityKey)
哪里(entityEntry.Entity是IHaveLogEntries)
让otherEndKey=relationEntry.otherEndKey(entityEntry.EntityKey)
让logEntryEntity=entityEntries
.其中(e=>e.EntityKey==otherEndKey)
.Select(se=>se.Entity)
.Cast()
.Single()
合并=新
{
RelationEntry=RelationEntry,
EntityEntry=EntityEntry,
LogEntryEntity=LogEntryEntity
}
集团合并
新{combined.LogEntryEntity,combined.EntityEntry.EntitySet.Name}
组合成一组
让added=combinedGroup
.Where(c=>c.RelationEntry.State==EntityState.Added)
.Select(c=>c.EntityEntry.Entity.ToString())
let deleted=combinedGroup
.Where(c=>c.RelationEntry.State==EntityState.Deleted)
.Select(c=>c.EntityEntry.Entity.ToString())
选择新的
{
combinedGroup.Key.LogEntryEntity,
Field=combinedGroup.Key.Name,
操作=操作。已修改,
FromValue=(对象)string.Join(“,”,deleted.ToArray()),
ToValue=(对象)string.Join(“,”,added.ToArray())
};
var l=q.ToList();
主要问题是在哪里对结果进行分组,在哪里使用combined.EntityEntry.EntitySet.Name
。如果可能的话,我想在IHaveLogEntries
实体上计算属性的名称。在本例中,该实体将是组合的.LogEntryEntity
感谢您的输入。我现在使用我拥有的relationEntry的ObjectStateEntry.EntitySet
属性解决了这个问题。有了它,我可以看到像这样的关系的名称实体\属性,我只需对那里的属性名称进行字符串提取,然后使用它从实体获取属性信息
对象
然后我添加了am属性,以便在必要时可以用更好的名称装饰属性
这是我在中间的某个地方添加的:
let propertyName = relationEntry
.EntitySet
.Name
.Split("_".ToCharArray())
.Last()
let property = logEntryEntity
.GetType()
.GetProperty(propertyName)
let nameAttribute = property
.GetCustomAttributes(typeof(NameAttribute), true)
.Cast<NameAttribute>()
.FirstOrDefault()
let name = nameAttribute != null ? nameAttribute.Name : property.Name
虽然我想知道是否有人有更好的想法,但到目前为止它似乎确实有效。字符串管理感觉有点不可靠。我知道这个问题很老了,但是其他人可能会从这个信息中受益。我有同样的问题要解决,不想依赖字符串解析。我发现实际的属性信息如下:
(PropertyInfo)objectStateEntry.EntitySet.ElementType.Members[0]。MetadataProperties[“ClrPropertyInfo”]。值
let propertyName = relationEntry
.EntitySet
.Name
.Split("_".ToCharArray())
.Last()
let property = logEntryEntity
.GetType()
.GetProperty(propertyName)
let nameAttribute = property
.GetCustomAttributes(typeof(NameAttribute), true)
.Cast<NameAttribute>()
.FirstOrDefault()
let name = nameAttribute != null ? nameAttribute.Name : property.Name
let combined = new {
FieldName = name,
RelationEntry = relationEntry,
EtityEntry = entityEntry,
LogEntryEntity = logEntryEntity
}
group combined by new { combined.LogEntryEntity, combined.FieldName }
into combinedGroup