0

我正在将 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; }
}

无论如何要确保由不同上下文创建的实体是相同的?IE

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)
4

2 回答 2

0

Entities created by different contexts (even different instances of the same context type) will not be same.

IMHO you must handle it yourselves by not allowing AnimalContext to create instances of objects defined in FruitContext - in your case Apple entity and assigning Apple to Dog after it is loaded by FruitContext - you will need to expose AppleId property on Dog. This could be probably somehow automated by handling the inter connection in ObjectContext.ObjectMaterialized event handler but it can slow down your object loading and it can make your contexts tightly coupled.

You can use either NotMapped attribute on Apple property or dog or use Ignore in fluent mapping for Apple class or Apple property in AnimalContext's mapping definition. If Apple has inverse navigation property to Dog, you will also have to ignore Dog on FruitContext.

于 2013-01-04T09:34:55.970 回答
0

为了确保由不同DbContext的 s 创建的实体是相同的,它们必须共享一个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(您显然可以对此进行简化以自动注册您需要的所有内容)。

于 2013-01-04T10:23:04.967 回答