如何优化以下查询?我们正在审查数据库中的实体框架查询,并尝试学习。
using (var context = new DataDbContext())
{
var query = (from u in content.Parents
where u.Children.Any(y = y.Age > 13)
select u);
foreach (var parent in query.ToList())
{
foreach (var children in owner.Children)
{
children.IsTeenager= true;
}
}
context.SaveChanges();
}
答案 0 :(得分:3)
没有什么好方法可以简化您在这里所做的事情。 EF倾向于将您推向从数据存储中读取一堆数据,在本地更新实体然后将这些更改写回的路径。这显然很慢。但是,您要在此处进行的操作是获取所有子项并设置IsTeenager
属性,这样您甚至不必关心Parent
对象,只需执行以下操作即可:
var children = context.Children.Where(c => c.Age < 13);
foreach(var child in children)
{
child.IsTeenager = true;
}
context.SaveChanges();
当然,使用原始SQL可以更轻松地完成此操作。例如:
context.Database.ExecuteSqlCommand("UPDATE Children SET IsTeenager = 1 WHERE Age < 13");
答案 1 :(得分:1)
没有太多要优化的地方,可以减少代码。逻辑有点奇怪
using (var context = new DataDbContext())
{
foreach (var child in content.Parents.Where(o => o.Children.Any(x => x.Age > 13)).SelectMany(o => o.Children))
{
children.IsTeenager= true;
}
context.SaveChanges();
}
或
using (var context = new DataDbContext())
{
var parents = content.Parents.Where(o => o.Children.Any(x => x.Age > 13));
foreach (var child in parents.SelectMany(o => o.Children))
{
children.IsTeenager= true;
}
context.SaveChanges();
}
答案 2 :(得分:1)
(from u in content.Parents
where u.Children.Any(y = y.Age > 13)
select u);
这似乎是一个错误。如果Parent
有一个14岁的孩子,另一个9岁的孩子,都将IsTeenager
设置为true。相反,如果他们只有一个13岁的孩子,那么这个孩子就不会将“少年”设置为true。
如果可能的话,我将IsTeenager
设为计算属性,而不是存储值
public bool IsTeenager => Age >= 13 && Age <= 19
那我根本就不必调用查询。
无法将查询更改为
content.Parents.SelectMany(o => o.Children).Where(o => o.Age >= 13 && o.Age <= 19)
可能我可以完全像这样跳过间接操作。
content.Children.Where(o => o.Age >= 13 && o.Age <= 19)
取决于数据库的结构。我真的需要和父母一起去吗?
除非我知道运行查询时IsTeenager
总是错误的,否则我可以过滤那些不需要它的内容,设置为:
content.Parents.SelectMany(o => o.Children).Where(o => !o.IsTeenager && o.Age >= 13 && o.Age <= 19)
或
content.Children.Where(o => !o.IsTeenager && o.Age >= 13 && o.Age <= 19)
答案 3 :(得分:0)
我之前在您的评论中看到了以下内容(已被删除):
这是我几个月前遇到的求职面试问题,甚至不确定
如果我在求职面试中向某人问这个问题,我希望他们能将以下情况告知我:
Age
也应这样做!public class PersonModel
{
public DateTime BirthDate { get; set; }
public int Age
{
get
{
var today = DateTime.Today;
// Calculate the age.
var age = today.Year - BirthDate.Year;
// Go back to the year the person was born in case of a leap year
if (BirthDate > today.AddYears(-age)) age--;
return age;
}
}
public bool IsTeenager
{
get
{
return Age >= 13 && Age < 20;
}
}
}
public class PersonModel
{
public DateTime BirthDate { get; set; }
public int Age { get; set; } // should be computed and mapped from sql
public bool IsTeenager { get; set; } // should be computed and mapped from sql
}
答案 4 :(得分:0)
要使用Entity Framework更新数据时,必须先将其检索到内存中(通过急切加载或延迟加载),然后进行修改。
有时会导致N + 1问题。这意味着对数据库服务器的N + 1次调用。而且,如果您使用某些基于云的托管(例如Azure或AWS),则将按请求收费。因此,这在财务上也将是昂贵的。
在您的情况下,我希望在“是”实体框架中执行此操作,但要使用存储过程。使用普通查询,但我不建议您采用这种方式。
使用存储过程将使您免于将数据带入内存并使用1个数据库调用获得结果的麻烦。