【问题标题】:How to initialize object in Entity Framework using POCO and DbContext after loading?加载后如何使用 POCO 和 DbContext 初始化实体框架中的对象?
【发布时间】:2012-09-03 09:50:53
【问题描述】:

我正在使用 EF5。我想初始化 DbContext 中包含的 DbSet 集合的每个对象,最好(但不一定)在初始化对象字段(但不一定与其他 POCO 的关系)之后。这可以简称为“施工后拦截”或“加载后拦截”。

初始化需要使用与 DbContext 实例并行存在的对象实例(当前用户设置等)来设置对象的一些属性。

所以基本上:

var settings = new Settings();
settings.PrintName = false;

var context = new MyDbContext();
// here initialize context so that every User object get initialized with settings
var john = context.Users.Where(x => x.Name == "John").FirstOrDefault();
Assert.AreEqual(john.Settings, settings);

除了遍历集合中的所有对象并手动设置属性之外,还有什么可能的方法来实现这一点?

【问题讨论】:

  • 如果不需要在 EF 为 POCO 赋值之后,为什么不在你的 POCO 类的构造函数中做呢?
  • 我需要将设置对象实例传递给构造函数。构造函数需要是:public User(Settings settings) - 可以在 DbContext 中使用非默认构造函数吗?
  • EF 将始终使用默认构造函数。

标签: c# entity-framework poco dbcontext entity-framework-5


【解决方案1】:

您可以使用在ObjectContext 上公开的ObjectMaterialized 事件:

var settings = new Settings();
settings.PrintName = false;

var dbContext = new MyDbContext();
var objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
objectContext.ObjectMaterialized += (sender, e) => {
    var user = e.Entity as User;
    if (e != null) {
       // Now you can call your initialization logic
       user.Settings = settings;
    }
};

var john = dbContext.Users.Where(x => x.Name == "John").FirstOrDefault();
Assert.AreEqual(john.Settings, settings);

ObjectMaterialized 事件应该在从数据库记录填充公共(标量和复杂)属性之后但在填充导航属性之前引发。

【讨论】:

  • 谢谢 - 确切的解决方案。只是为了完成答案,您是否知道是否有另一种方法可以仅处理特定类型的实体(来自 DbSet 的 T)以便不需要类型检查?
  • 不,我不知道这种方法。
猜你喜欢
  • 2015-02-21
  • 2011-03-04
  • 1970-01-01
  • 1970-01-01
  • 2012-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
相关资源
最近更新 更多