具有相关实体的通用存储库

时间:2017-02-06 22:48:22

标签: c# entity-framework entity-framework-6

我有一个像这样的通用存储库:

public interface IGenericRepository<TObject> where TObject : class
{
    TObject Add(TObject t);
}

public class GenericRepository<TObject> : IGenericRepository<TObject> where TObject : class
{
    private readonly DbContext context;

    public GenericRepository(DbContext context)
    {
        this.context = context;
    }

    public virtual TObject Add(TObject t)
    {
        context.Set<TObject>().Add(t);
        context.SaveChanges();
        return t;
    }
}

在我的EF模型中,我有作者和书,它有1:N的关系。作者有一个导航属性“书籍”到书和书有作者“作者”。

然后我有这样的通用服务:

public class GenericService<TObject> : IGenericService<TObject> where TObject : class
{
    private readonly IGenericRepository<TObject> context;

    public GenericService(IGenericRepository<TObject> ct)
    {
        context = ct;
    }

    public TObject Add(TObject data)
    {
        return context.Add(data);
    }
}

我有这样的单元测试:

[TestMethod]

public void TestAdd()
{
    var b = new Book();
    b.AuthorId = 1;
    b.Name = "Test";
    b.ISBN = "1111";
    var service = new GenericService(new GenericRepository<Book>(new MyDbEntities()));
    var newBook = service.Add(b);
    Assert.AreEqual("Author1", newBook.Author.Name);
}

问题是newBook.Author为null,这意味着Add方法中新创建的对象没有任何相关实体。我知道这种问题的解决方案之一是使用.include()来包含所有相关实体,但在我的情况下,是一个通用的存储库,我不知道如何做到这一点。

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:1)

您的问题是如何实例化Book对象。而不是

var b = new Book();
你应该做点什么

var b = service.Create();

创建是一种应该通过EF返回新书的方法:

context.Set<TObject>().Create();

使用create,EF将返回一个代理对象,因此导航属性将在附加到上下文后加载,假设所有引用都正常并且DatabaseContext使用延迟加载。

检查:https://stackoverflow.com/a/31406426/1270813

顺便说一句,单元测试验证延迟加载功能的原因是什么?它仅用于学习目的吗?根据经验,您应该测试代码,而不是其他框架。

此致