我有以下方法从脚手架模板自动生成存储库: -
public Group Find(int id)
{
    return context.Groups.Find(id);
}
但由于组对象有哪些我需要两个导航属性,所以我想包括.Include,所以我代替.find用.where: -
public Group Find(int id)
{
    return context.Groups.Where(c=>c.GroupID==id)
                         .Include(a => a.UserGroups)
                         .Include(a2 => a2.SecurityRoles)
                         .SingleOrDefault();
}
但我的问题是我怎么能应用.Include与.find()而是采用.Where()?
Not*_*ple 39
我只是想着实际发现了什么.@lazyberezovsky是正确的包括,并发现不能相互结合使用.我认为这是非常慎重的,这就是为什么:
DbSet上的Find方法使用主键值来尝试查找上下文跟踪的实体.如果在上下文中找不到该实体,则将向数据库发送查询以在那里找到该实体.如果在上下文或数据库中找不到实体,则返回Null.
查找与以下两种重要方式使用查询不同:
- 只有在上下文中找不到具有给定键的实体时,才会往返数据库.
- Find将返回处于已添加状态的实体.也就是说,Find将返回已添加到上下文但尚未保存到数据库的实体.
(来自http://msdn.microsoft.com/en-us/data/jj573936.aspx)
因为find是一种优化方法,所以可以避免需要访问服务器.如果您已经跟踪了实体,这很好,因为EF可以更快地返回它.
但是,如果它不仅仅是我们所追求的这个实体(例如我们想要包含一些额外的数据),那么就无法知道这些数据是否已经从服务器加载.虽然EF可能与连接一起进行此优化,但由于它对数据库状态做出假设,因此容易出错.
我认为包含并发现无法一起使用是一个非常慎重的决定,以确保数据完整性和不必要的复杂性.当您想要进行连接以始终转到数据库以执行该连接时,它会更清晰,更简单.
你不能.查找在DbSet<T>类型上定义的方法,它返回实体.你不能打电话Include的实体,那么唯一可能的选项调用Find 后 Include.你需要DbSet<T>输入,但Include("UserGroups")会返回DbQuery<T>,并且Include(g => g.UserGroups)还会返回DbQuery<T>:
public static IQueryable<T> Include<T>(this IQueryable<T> source, string path) 
    where T: class
{
    RuntimeFailureMethods.Requires(source != null, null, "source != null");
    DbQuery<T> query = source as DbQuery<T>;
    if (query != null)    
        return query.Include(path); // your case
    // ...
}
DbQuery<T>因此不是孩子的DbSet<T>方法Find是不可用的.还要记住,Find首先在本地对象中查找实体.如果它们没有加载,它将如何包含一些引用的实体?
| 归档时间: | 
 | 
| 查看次数: | 25444 次 | 
| 最近记录: |