如何将这些linq查询合并为一个?

时间:2010-01-23 00:07:11

标签: c# linq linq-to-sql

作为LINQ的新手,我创建了几个查询,并希望将它们组合成一个,但我不知道该怎么做。他们在这里:

var u = dc.Users.Where(w => w.UserName == userName).SingleOrDefault();

var m = dc.Memberships.Where(w => w.UserId == u.UserId).SingleOrDefault();

m.PasswordQuestion = securityQuestion;
m.PasswordAnswer = securityAnswer;

dc.SubmitChanges();

dc.Usersaspnet_Users
dc.Membershipaspnet_Membership

另外,SingleOrDefaultFirstOrDefault之间有什么区别?

4 个答案:

答案 0 :(得分:5)

不确定他们是否有关系(他们应该)。如果他们这样做,那么linq-to-sql设计器将为您提供成员资格对象上的User属性(或者相反)。然后你可以这样写:

var membership = dc.Memberships.Where(x => x.User.UserName == userName).SingleOrDefault();

如果他们没有关系,你可以这样写:

var membership = (from m in dc.Membership join u in dc.Users on u.UserId equals m.UserId
                  where u.UserName == userName
                  select u).SingleOrDefault();

SingleOrDefault()和FirstOrDefault()之间的区别在于SingleOrDefault()假定只有一个项目与查询匹配。如果两个项匹配查询,则会抛出异常。如果您使用FirstOrDefault()并且有两个项目与查询匹配,那么将选择第一个项目。

答案 1 :(得分:3)

SingleOrDefault表示“如果没有元素,请给我默认值,如果有,请给我,否则,抛出异常”。 FirstOrDefault的意思是“如果没有元素然后给我默认,否则给我第一个”。

至于关于组合查询的问题 - 为什么?如果代码运行良好,为什么要改变呢?

要回答您没有问过的问题:组合查询的常用方法是使用查询延续。常见的模式是:

var q1 = from y in something 
         somequeryclauses;
var q2 = from x in q1 
         someotherquerqyclauses;

你可以把它写成一个像这样的大查询:

var q2 = from x in (from y in something 
                    somequeryclauses) 
         someotherqueryclauses;

难以阅读。您可以将这两个查询与查询延续结合起来:

var q2 = from y in something 
         somequeryclauses 
         into x
         someotherqueryclauses;

有意义吗?

答案 2 :(得分:1)

如果序列包含多个元素,SingleOrDefault将抛出错误,而FirstOrDefault则不会。在这种情况下,您可能想要FirstOrDefault,因为用户可以拥有多个成员资格。

var m = dc.MemberShips where(w => w.UserId.UserName == userName).FirstOrDefault();

答案 3 :(得分:1)

我面前没有Visual Studio,但它会是这样的:

var m = dc.Memberships.Where(w => w.Users.UserName == userName).SingleOrDefault(); 

m.PasswordQuestion = securityQuestion; 
m.PasswordAnswer = securityAnswer; 

dc.SubmitChanges(); 

w.Users允许您遵循成员资格和用户表之间的外键链接。

如果返回多个结果,SingleOrDefault将抛出异常。 FirstOrDefault仅返回第一条记录。