我有实体
Blog{ blogId, name, creatorUserId }
BlogSettings{ blogId, userId, column1 }
现在我有一个接受blogId
和userId
的方法,我正在查询Blog
(不是BlogSettings
)
Blog
包含BlogSettings
。
我该怎么做?
如果我写context.Blogs.Include("BlogSettings").Where( b => b.BlogId == blogId)
效率非常低,因为我只需要其userId == userId的BlogSettings。
Note:
我不是在查询BlogSettings。正如您所看到的,我正在查询Blog集合。
答案 0 :(得分: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);
//
}
答案 1 :(得分:0)
虽然您在Blog
上正在查询,但您可能会发现针对BlogSettings
撰写查询并添加.Include("Blog")
更有效。
Presumaby你只有一个BlogSettings
用于UserId和BlogId的组合;也许这是由一个独特的约束强制执行的。如果是这种情况,这将非常快:
var blogAndSettings = (from s in context.BlogSettings
.Include("Blog")
where s.BlogId = blogId && s.UserId = userId
select s).SingleOrDefault();
这需要您创建一个名为BlogSettings
的{{1}}到Blog
的导航属性。
答案 2 :(得分:0)
这将执行Blog
和BlogSettings
表之间的联接,但只是实现BlogSetting
个实体。
var settings = context.Blogs.Where( b => b.BlogId == blogId && b.CreatorUserId = userId)
.SelectMany(x => x. BlogSettings);
答案 3 :(得分:-1)
context.Blogs.Include("BlogSettings").SingleOrDefault( b => b.BlogId == blogId);