配置EF DAO以返回已分离的实体

时间:2014-03-07 10:14:39

标签: c# entity-framework

是否可以(使用属性或其他内容)配置DAO方法以返回分离的对象?我很想这样做,因为我想确保DAO预先获取从DAO返回的下游代码可能需要的任何字段和关系。如果实体是分离的,那么将抛出异常并且我们可以轻松地识别问题。通过延迟解决关系,您可能会在没有意识到的情况下向DB发送多个额外请求。

例如,假设我有一个DAO类:

public class TestDao
{
    private readonly MyContext _db;

    public TestDao(MyContext db)
    {
        _db = db;
    }

    public List<Group> AllGroups()
    {
        return _db.Groups.ToList();    
    }
}

然后说我有一个Dao的客户:

public void TestGetAllGroups()
{
    var groups = _testDao.AllGroups();

    foreach (var group in groups)
    {
        var x = group.Memberships;    
        Console.WriteLine( group.id + ":" + x.Count );
    }    
}

此代码有效,但测试工具中的每次迭代都会导致对数据库的新命中,因为数据库尚未预先提取(包括)成员资格关系。

我正在寻找让这段代码抛出异常的最好方法,说group.Memberships是null或者什么。如果在退出TestDao.AllGroups()时分离了组实例,那么这就行了,并提醒我们DAO需要在从AllGroups()方法返回之前包含成员资格

1 个答案:

答案 0 :(得分:0)

看起来您可以禁用延迟加载关系。在我的Context类中:

 public partial class MyContext : DbContext
    {
        static MyContext()
        {
            Database.SetInitializer<MyContext>(null);
        }

        public MyContext() : this("Name=MyContext")
        {
        }

        public MyContext(string name): base(name)
        {
            Configuration.LazyLoadingEnabled = false;
        }
        ...
}

但是,除此之外,我还需要确保EF实体构造函数不会为一对多关系创建空列表。这些似乎默认添加了架构优先实体代码生成工具:

public partial class Group
{
    public Group()
    {
        //Remove this line!
        //this.Memberships = new List<Membership>();
    }

    public int id { get; set; }
    public string name { get; set; }

    public virtual ICollection<Membership> Memberships { get; set; }

}

现在,我的测试工具将抛出NPE,除非我将.Include放入Dao以包含成员资格