Linq to sql 空表中的Linq到SQL选择、更新和提交结果

Linq to sql 空表中的Linq到SQL选择、更新和提交结果,linq-to-sql,select,Linq To Sql,Select,鉴于: 使用(DataContext ctx=newdatacontext(props.ConnectionString)) { IQueryable电子邮件=空; 尝试 { emails=ctx.emails.Where(e=>!(e.IsLocked | | e.IsSent)); foreach(电子邮件中的var e) { e、 IsLocked=true; } ctx.SubmitChanges(); } } //在这里处理电子邮件 为什么提交更改()后电子邮件是空的?有没有办法避免

鉴于:

使用(DataContext ctx=newdatacontext(props.ConnectionString))
{
IQueryable电子邮件=空;
尝试
{
emails=ctx.emails.Where(e=>!(e.IsLocked | | e.IsSent));
foreach(电子邮件中的var e)
{
e、 IsLocked=true;
}
ctx.SubmitChanges();
}
}
//在这里处理电子邮件

为什么提交更改()后电子邮件是空的?有没有办法避免在IsLocked设置为true后清空表?

ctx.Emails
可能不是空的。每次调用时都会对收集的
电子邮件进行评估

如果您想让电子邮件在初次通话时返回,您可以这样做:

using (DataContext ctx = new DataContext(props.ConnectionString))
{
    IQueryable<Email> emails = null;
    try
    {
       emails = ctx.Emails.Where(e => !(e.IsLocked || e.IsSent));
       foreach (var e in emails)
       {
           e.IsLocked = true;
       }
       ctx.SubmitChanges();
    }
}

// do something with emails here

托马斯的回答是正确的,但我也要试着解释一下

emails
集合是一个枚举,当您调用它时会重新计算它。想象一下这样

emails = ctx.Emails.Where(e => !(e.IsLocked || e.IsSent)).ToList().AsQueryable();
//另一个方法。。。
IEnumerable GetEmails()
{
返回ctx.email.Where(e=>!(e.IsLocked | | e.IsSent));
}
//主方法内部(&I)
foreach(GetEmails()中的变量e)
{
e、 IsLocked=true;
}
ctx.SubmitChanges();
//现在,如果您检查结果,它将被重新评估
获取电子邮件();
这是故意的行为


如果你想“收到”这些电子邮件,对它们做些什么,并保持收集,你应该把它们放在一个列表/数组中。枚举不是一个真正的集合,它更像是一个在查询集合时返回集合的函数。

如果这没有意义,请告诉我,我可以尝试更好地解释它。实际上,它似乎是。当我一步一步地完成代码并越过这一点时,在“本地人”窗口中打开电子邮件时会显示“枚举未产生任何结果”。不过,ToList()确实起到了作用。那么,SubmitChanges()是否“清除”表?foreach循环显然导致了所有匹配记录的延迟加载……好吧,让我更详细地解释一下
foreach(电子邮件中的var e)
是第一次评估(因此进入数据库)。然后将每封电子邮件的
IsLocked
更新为true<代码>ctx.SubmitChanges()
将数据库中每封电子邮件的
IsLocked
更新为true。如果随后调用变量
emails
,则语句
ctx.emails.Where(e=>!(e.IsLocked | | e.IsSent))
将再次求值(从而再次访问数据库),但随后所有电子邮件
IsLocked
都为真,因此它返回一个空集合。
// another method...
IEnumerable<Email> GetEmails()
{
    return ctx.Emails.Where(e => !(e.IsLocked || e.IsSent));
}

// & inside your main method
foreach (var e in GetEmails())
{
    e.IsLocked = true;
}
ctx.SubmitChanges(); 

// now if you check the result it will be reevaluated
GetEmails();