[英]How to get the original values from a navigation collection property in Entity Framework Core?
With Entity Framework Core, I need to check the original values of a navigation property inside my entity but i can't find a way to do it.使用 Entity Framework Core,我需要检查我的实体内导航属性的原始值,但我找不到方法来做到这一点。
I'm able to read the original and the current values of the actual entity and also his reference property but the OriginalValue property is missing when I read the navigation property.我能够读取实际实体的原始值和当前值以及他的引用属性,但是当我读取导航属性时缺少 OriginalValue 属性。
Here's what I been able to do so far.到目前为止,这是我能够做的。
var entries = ChangeTracker.Entries<Book>()
.Where(x => x.State == EntityState.Modified)
.ToList();
foreach (var entry in entries)
{
// read the entity current & original values
var currentTitleValue = entry.Property(x => x.Title).CurrentValue;
var originalTitleValue = entry.Property(x => x.Title).OriginalValue;
// read the reference object current & original values
var promotionReferenceEntry = entry.Reference(x => x.Promotion);
var currentPromotionPriceValue = promotionReferenceEntry.TargetEntry.Property(x => x.Price).CurrentValue;
var originalPromotionPriceValue = promotionReferenceEntry.TargetEntry.Property(x => x.Price).OriginalValue;
// read the navigation object current & original values
var authorsCollectionEntry = entry.Collection(x => x.AuthorBooks);
var currentAuthorIds = authorsCollectionEntry.CurrentValue.Select(x => x.AuthorId).ToList();
var originalAuthorIds = ?????;
}
Here is a way to get the reference properties in the context as well as its original values:这是获取上下文中的引用属性及其原始值的一种方法:
var entries = ChangeTracker.Entries<Book>()
.Where(x => x.State == EntityState.Modified)
.ToList();
foreach (var entry in entries)
{
// If it is Added/Deleted, you can't get the OriginalValues/CurrentValues respectively.
// So make it Modified for the meanwhile.
var tempState = entry.State;
entry.State = EntityState.Modified;
// Clone the Entity values (the original ID, Current ID of the navigation
var currentValues = Entry(entry.Entity).CurrentValues.Clone();
var originalValues = Entry(entry.Entity).OriginalValues.Clone();
// Set the Entity values to the OriginalValues and load the reference
Entry(entry.Entity).CurrentValues.SetValues(originalValues);
Entry(entry.Entity).Reference(x => x.Promotion).Load();
// Store the Original Reference value in a variable
var promotionReferenceEntryOriginalValue = entry.Reference(x => x.Promotion).CurrentValue;
// Set the Entity values back to CurrentValues and load the reference
Entry(entry.Entity).CurrentValues.SetValues(currentValues);
Entry(entry.Entity).Reference(x => x.Promotion).Load();
// Store the Current Reference value in a variable
var promotionReferenceEntryCurrentValue = entry.Reference(x => x.Promotion).CurrentValue;
// Set the Entry State back to its original State Added/Modified/Deleted
entry.State = tempState;
// read the entity current & original values
var currentTitleValue = entry.Property(x => x.Title).CurrentValue;
var originalTitleValue = entry.Property(x => x.Title).OriginalValue;
// read the reference object current & original values
//var promotionReferenceEntry = entry.Reference(x => x.Promotion);
var currentPromotionPriceValue = promotionReferenceEntryCurrentValue.Price; // promotionReferenceEntry.TargetEntry.Property(x => x.Price).CurrentValue;
var originalPromotionPriceValue = promotionReferenceEntryOriginalValue.Price; // promotionReferenceEntry.TargetEntry.Property(x => x.Price).OriginalValue;
}
To make it dynamic, remove the type <Book>
from ChangeTracker.Entries<Book>()
and loop though the entry.Entity
properties inside the foreach (var entry in entries)
loop:要使其动态化,请从ChangeTracker.Entries<Book>()
中删除类型<Book>
并在foreach (var entry in entries)
循环中遍历entry.Entity
属性:
foreach (var propertyInfo in entry.Entity.GetType().GetProperties())
{
var propertyName = propertyInfo.Name;
//Do the loads here...
//Get the values
}
Check if it is a navigation reference or a collection reference by trying to access it using extra methods and check if it is null or not, not null means it is a valid property to try and load()
it:通过尝试使用额外的方法访问它来检查它是导航引用还是集合引用,并检查它是否为空,不为空意味着它是一个有效的属性来尝试load()
它:
private DbPropertyEntry GetProperty(DbEntityEntry entry, string propertyName)
{
try
{
return entry.Property(propertyName);
}
catch { return null; }
}
private DbReferenceEntry GetReference(DbEntityEntry entry, string propertyName)
{
try
{
return entry.Reference(propertyName);
}
catch { return null; }
}
private DbCollectionEntry GetCollection(DbEntityEntry entry, string propertyName)
{
try
{
return entry.Collection(propertyName);
}
catch { return null; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.