我很难获得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”这样的短片?我想我已经设置了导航属性,但我不确定如何正确使用它们,或者我是否可以通过修改它们来使它们更好。
感谢您阅读
答案 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();