1

在将项目从 EntityObject 生成器切换到 DbContext 后,我​​在新对象上使用一些导航属性时遇到了问题。我已经花费了大量时间来研究这个问题,但我离理想的解决方案还差得远。

一、生成的类定义:

public partial class Category
{
    public Category()
    {
        this.Limits = new HashSet<Limit>();
    }

    public int CategoryId {get; set;}
    public string Name {get; set;}
    public virtual ICollection<Limit> Limits { internal get; set; }
}

public partial class Limit
{
    public int CategoryId {get; set;}
    public string Description {get; set;}
    internal virtual Category Category { get; set; }
}

我正在使用以下代码在集成测试期间创建测试数据:

using (GFCAMDataContext db = new GFCAMDataContext())
{
    limit = new Limit()
    {
        CategoryId = testData.CategoryId,
        Description = "SignerController.Update"
    };

    db.Limits.Add(limit);
    db.SaveChanges();
}

如果没有任何其他更改,我新创建的 Limit 对象的 Limit.Category 属性不会返回任何内容。但是,如果我在调用 SaveChanges 之前从 DbContext 查询所需的类别,我的新限制上的导航属性开始返回关联的类别。使用 ObjectContext,Category 属性会在我没有任何干预的情况下更新。

我希望有与 ObjectContext 相同的行为,但我似乎找不到实现这一目标的方法。我已经看到了几个建议的解决方案:

  • 公开导航属性。这具有相同的行为,并且是不可取的,因为公共导航属性可能会在序列化过程中导致问题,并且在我的业务层之外不需要。

  • 将所有属性设为公共虚拟并使用 DbSet.Create 来确保创建代理。这导致了相同的行为,并且不一定是可取的,因为我有代码动态创建实例(即在创建实体实例时我没有访问 DbSet 的权限)。

有没有人对解决这个问题有任何建议?

4

1 回答 1

0

一种解决方案是显式加载嵌套实体:

db.SaveChanges();
db.Entry(person).Reference(z => z.Category).Load();

启用代理时,另一个选项确实是调用DbSet.Create<T>(). 如果您在创建实体时无权访问该DbSet实例,您可能希望在您的存储库接口中公开一个允许这样做的公共方法。例如:

public interface IRepository<T>
{
    T Add(T entity);

    T GetById(...);

    void SaveChanges();

    ...

    T CreateInstance(); // Concrete implementation have access to DbSet and uses DbSet.Create<T>()
}
于 2013-02-06T13:22:58.733 回答