更好地制作LINQ查询

时间:2010-08-24 12:26:50

标签: c# linq

我很难获得LINQ语法..如何以更好的方式执行此命令?

var user = (from u in context.users
            where u.email.Equals(email)
            select u).Single();
var pinToUser = (from ptu in context.pintousers
                 where ptu.user_id.Equals(user.id)
                 select ptu).Single();
var pin = (from p in context.pins
           where p.idpin.Equals(pinToUser.pin_idpin)
           select p).Single();

return pin;

如您所见,有一个表用户,一个表pintouser和一个表针。 Pintouser引用用户和引脚。是否有可能写一些像“user.pintouser.pin”这样的短片?我想我已经设置了导航属性,但我不确定如何正确使用它们,或者我是否可以通过修改它们来使它们更好。

感谢您阅读

4 个答案:

答案 0 :(得分:8)

使用联接将所有内容重写为单个干净查询。如果我正确地阅读了您的查询,这应该会给您正确的结果:

var pin = (from u in context.users
          join ptu in context.pintousers on u.id equals ptu.user_id
          join p in context.pins on ptu.pin_idpin equals p.idpin
          where u.email == email
          select p).Single();

但请记住,如果此查询返回除单个结果之外的任何内容,则代码将抛出异常。

如果您想要处理获得一行或没有行的可能性,那么您应该使用SingleOrDefault()

如果您想要处理获取任意数量行的可能性,那么您应该真正使用FirstOrDefault()

答案 1 :(得分:3)

请注意,如果您在数据库中设置了外键关系,Linq-to-Sql应自动为您提供连接:

var pin = (from u in context.users 
      where u.email == email 
      select u.pintouser.pin).Single(); 

这意味着你可以将其减少为:

var pin = context.users.Where(u=>u.email == email)
                       .Select(u=>u.pintouser.pin)
                       .Single();

(更新注意:我原先建议如下,这个更短,但我相信它会导致两次往返数据库)

var pin = context.users.Single(u=>u.email == email).Single().pintouser.pin;

现在,.pintouser.pin是安全的,因为Single()将始终返回user个对象(或抛出异常)。

答案 2 :(得分:2)

你应该使用join,正如@JustinNiessner指出的那样,但这是另一种编写查询的方式。

var user = context.users.Single(u => u.email == email);
var pinToUser = context.pintousers.Single(ptu => ptu.user_id == user.id);
var pin = context.pins.Single(p => p.idpin == pinToUser.pin_idpid);

答案 3 :(得分:1)

由于你有导航属性,不妨使用它们:

Pin pin =
(
  from u in context.Users
  where u.email == email
  from ptu in u.pintousers
  let p = ptu.pin
  select p
).Single();