1

我有实体

Blog{ blogId, name, creatorUserId }

BlogSettings{ blogId, userId, column1  }

现在我有一个方法可以接受blogId并且userId我正在查询Blog(not BlogSettings)

Blog包含BlogSettings.

我该怎么做?

如果我写context.Blogs.Include("BlogSettings").Where( b => b.BlogId == blogId)那将是非常低效的,因为我只需要 userId == userId 的 BlogSettings。

Note:我没有在 BlogSettings 上查询。如您所见,我正在查询博客集合。

4

4 回答 4

1
var blogWithSetting = context.Blogs
    .Where(b => b.BlogId == blogId)
    .Select(b => new
    {
        Blog = b,
        BlogSetting = b.BlogSettings.FirstOrDefault(bs => bs.UserId == userId)
    })
    .SingleOrDefault();

if (blogWithSetting != null)
{
    Blog blog = blogWithSetting.Blog;
    //
}

这种投影是在单次往返数据库中获得结果的唯一方法,因为预先加载Include不支持对包含的子集合进行任何过滤或排序。如果您不禁用更改跟踪并且关系不是多对多,则将使用单个加载的blog.BlogSettings自动填充。否则,您必须使用结果对象的属性手动填充集合:BlogSetting

if (blogWithSetting != null)
{
    Blog blog = blogWithSetting.Blog;
    blog.BlogSettings = new List<BlogSetting>();
    blog.BlogSettings.Add(blogWithSetting.BlogSetting);
    //
}
于 2012-06-04T17:40:15.723 回答
0

虽然理论上您正在查询,但您可能会发现编写查询和添加Blog查询更有效。BlogSettings.Include("Blog")

假设您只有一个BlogSettings用于 UserId 和 BlogId 的组合;也许这是由一个独特的约束来强制执行的。如果是这样的话,这将非常快:

    var blogAndSettings = (from s in context.BlogSettings
                                            .Include("Blog")
                           where s.BlogId = blogId && s.UserId = userId
                           select s).SingleOrDefault();

这将要求您创建一个导航属性 from BlogSettingsto Blogcalled Blog

于 2012-06-04T17:53:35.377 回答
0

Blog这将在和表之间执行连接,BlogSettings但只是具体化BlogSetting实体。

var settings = context.Blogs.Where( b => b.BlogId == blogId && b.CreatorUserId = userId)
                            .SelectMany(x => x. BlogSettings);
于 2012-06-04T17:58:09.197 回答
-1
context.Blogs.Include("BlogSettings").SingleOrDefault( b => b.BlogId == blogId);
于 2012-06-04T17:58:03.813 回答