【发布时间】:2014-09-09 20:12:13
【问题描述】:
我从一个 DBContext 加载了一个实体,并对其进行了一些更改。如果我然后创建另一个 DBContext,我将如何从数据库中将相同的实体加载到其中?这需要跨不同实体通用,因此我不能只查找 ID 相同的位置 - 某些实体可能具有不同的关键属性。
问题背后的原因是我想使用加载到第二个上下文中的实体来验证第一个上下文中的一些更改属性,并将以前的值与新值进行比较。所以第二个上下文在第一个实体的验证期间是纯只读的。
编辑
我尽量保持简单,我认为需要更多细节。
假设我有这个实体:
public partial class SomeEntity : IValidatableObject
{
public int Id { get; set; }
public int StatusId { get; set; }
//... Other properties
public virtual ICollection<SomeOtherEntity> relatedEntity { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext){
// validation code
}
}
我要做的是在验证实体时,将 StatusId 与数据库中当前的 StatusId 进行比较,并可能发生验证错误 - 例如说 StatusId 不能从1到5。作为
正如 Pawel 提到的,这可以通过使用 OriginalValues 来完成,但是我还需要能够根据 relatedEntity 中的值验证 StatusId。例如,如果 relatedEntity 中存在某些值,则不能将 StatusId 从 1 更改为 2。
因此,为了进行此验证,我需要数据库中未修改形式的 SomeEntity 对象的副本,以便可以将其与我尝试修改的对象进行比较。
这有点乱,但我想出的想法是:
-
使
SomeEntity成为新的空接口IMyValidationInterface的成员。public interface IMyValidationInterface { } public partial class SomeEntity : IValidatableObject, IMyValidationInterface { public int Id { get; set; } // .... } -
覆盖
MyDBContext上的ValidateEntity方法,以便将具有原始值的对象传递到实体上的验证方法中。public class MyDBContext : DbContext { protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items) { if (entityEntry.Entity is IMyValidationInterface) { var _validationContext = new MyDbContext(); /// TODO: some code here to load a duplicated version of /// the entity from the database var originalEntity; // unchanged entity is here // unmodified entity is passed as an item to the entities // Validate method items.Add("OriginalEntity", originalEntity); } return base.ValidateEntity(entityEntry, items); } } public partial class SomeEntity : IValidatableObject, IMyValidationInterface { // ..... public IEnumerable<ValidationResult> Validate(ValidationContext validationContext){ // validation code if (validationContext.Items.ContainsKey("OriginalEntity")){ var originalEntity = (SomeEntity)validationContext.Items["OriginalEntity"]; // do validation here and yield return any validation errors } } }
我卡在上面的 sn-p 中的 TODO 部分。
我是不是走错路了?
【问题讨论】:
-
您是否正在保存从第一个 DBContext 加载的已修改实体上的更改?
-
也许您可以使用 OriginalValues 而不必拥有多个上下文?
-
我认为您只需要知道对实体进行了哪些更改即可进行验证。如果有帮助请查看此链接,[LINK]:stackoverflow.com/questions/3265257/…
-
您是否考虑过直接查询 EF 模型以从实体中获取实际的关键信息?
标签: c# asp.net-mvc entity-framework