我正在将Entity Framework 4.4用于现有的.NET 4.0应用程序。它有一些模块化,我需要每个架构有一个DbContext
。例如
public class AnimalContext : DbContext // animal schema
{
public IDbSet<Dog> Dogs { get; set; }
public IDbSet<Cat> Cats { get; set; }
}
和
public class FruitContext : DbContext // fruit schema
{
public IDbSet<Apple> Apples { get; set; }
public IDbSet<Pear> Pears { get; set; }
}
某些实体引用不同架构中的实体,例如
public class Dog
{
public Apple Apple { get; set; }
}
无论如何确保不同上下文创建的实体是相同的吗?即。
var animals = new AnimalContext()
var fruits = new FruitContext()
var dog = animals.Dogs.First();
var apple = fruits.Apples.First(x => x == apple)
// and object.ReferenceEquals(apple, dog.Apple)
答案 0 :(得分:0)
由不同上下文创建的实体(即使是相同上下文类型的不同实例)也不会相同。
恕我直言,您必须自己处理它,不允许AnimalContext
创建FruitContext
中定义的对象实例 - 在您的案例Apple
实体中并将Apple
分配给{{1}在Dog
加载后,您需要在FruitContext
上公开AppleId
属性。这可能通过在Dog
事件处理程序中处理内部连接而以某种方式自动化,但它可以减慢对象加载速度,并且可以使您的上下文紧密耦合。
您可以在ObjectContext.ObjectMaterialized
属性或狗上使用NotMapped
属性,或在Apple
类或Ignore
属性的Apple
属性中使用Apple
映射定义。如果AnimalContext
具有反向导航属性Apple
,则您还必须忽略Dog
上的Dog
。
答案 1 :(得分:0)
为了确保由不同DbContext
创建的实体相同,必须共享一个可以通过ObjectContext
构造函数传递的公共DbContext
。
使用Code First方法创建公共ObjectContext
的方法是通过DbModelBuilder
- 访问其中一种方法的推荐方法是通过覆盖继承类的OnModelCreating(DbModelBuilder)
方法来自DbContext
。
例如:
public class MasterContext : DbContext
{
public MasterContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
public static implicit operator ObjectContext(MasterContext obj)
{
if (obj == null)
{
throw new ArgumentNullException("obj");
}
var adapter = (IObjectContextAdapter)obj;
return adapter.ObjectContext;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Dog>();
modelBuilder.Entity<Cat>();
modelBuilder.Entity<Apple>();
modelBuilder.Entity<Pear>();
}
}
public class AnimalContext : DbContext
{
public AnimalContext(ObjectContext context)
: base(context, false)
{
}
public IDbSet<Dog> Dogs { get; set; }
public IDbSet<Cat> Cats { get; set; }
}
public class FruitContext : DbContext
{
public FruitContext(ObjectContext context)
: base(context, false)
{
}
public IDbSet<Apple> Apples { get; set; }
public IDbSet<Pear> Pears { get; set; }
}
//...
var master = new MasterContext("my connection")
var animals = new AnimalContext(master)
var fruits = new FruitContext(master)
var dog = animals.Dogs.First();
var apple = fruits.Apples.First(x => x == apple)
// Passes
Debug.Assert(object.ReferenceEquals(apple, dog.Apple))
这里需要注意的重要一点是,OnModelCreating
中的MasterContext
必须注册所有奴隶DbContexts
中使用的每种类型(你可以明显地将其添加到自动注册所有内容中需要)。