我意识到这是部分主观的,但我对社区意见一般都很好奇,并且无法成功找到解决这个问题的现有问题。
我与同事就L2EF查询中的特定Select语句进行了一些宗教辩论。
.Select(r =>
{
r.foo.Bar = r.bar;
r.foo.Bar.BarType = r.Alpha;
if (r.barAddress != null)
{
r.foo.Bar.Address = r.barAddress;
r.foo.Bar.Address.State = r.BarState;
}
if (r.baz != null)
{
r.foo.Bar.Baz = r.baz;
if (r.bazAddress != null)
{
r.foo.Bar.Baz.Address = r.bazAddress;
r.foo.Bar.Baz.Address.State = r.BazState;
}
}
return r.foo;
})
警告:
r
是匿名的就个人而言,我认为(a)select子句不应该改变值,它应该仅仅是项目。他的反驳论点是他没有改变任何东西,他只是确保一切都由于数据库查询而被正确初始化。其次,我认为一旦他开始进入完整的代码块并返回语句,就应该定义一个方法,甚至是Func<T, U>
,而不是全部内联。这里的复合器同样是输入是匿名的,因此需要定义一个类型。但是,尽管如此,我们仍在辩论一般性观点。
那么,lambda表达式什么时候做的太多了?你在哪里画出沙子中的模糊线?
答案 0 :(得分:2)
我的第一直觉是与你达成一致,主要是关于规模和复杂性。
但是,它被用在一个上下文中,它将(或有时)执行为除.NET代码之外的其他东西(特别是如果它变成SQL查询的一部分),我会变得更加宽容它的。
所以,这就是我绘制模糊线的地方,也是我再次移动它的原因:)
答案 1 :(得分:1)
我也同意Select()应该用于投影。我宁愿看到使用“let”关键字提前进行检查,以便Select()中的投影可以保持清洁。这将使Select()能够引用使用“let”设置的变量。
答案 2 :(得分:1)
我个人认为这不是一个长长的lambda表达。我想你将会看到更复杂,并且将来会嵌套lambda。特别是像Rx这样的东西。
至于状态变化......好吧,他在这里只是初始化价值观。我只关心它是否将状态分配给lambda之外的某个变量,但这都是r的初始化,所以对我来说似乎很好。
答案 3 :(得分:1)
在看到烦扰我的事情之前,我不得不盯着这一段时间。
这需要一个重构。
我花了很长时间才读到了lambda的意图。
我不确定我是否可以支持你对Select的工作的定义,但我同意你能保持lambda越短越好。如果需要进行dB提取后的初始化,请将其分解以重复使用。
答案 4 :(得分:0)
你必须考虑其他选择......是否有更好的地方来放置这种逻辑。无论哪种方式,你循环遍历LINQ中的每个实体,或者在foreach循环中,来完成额外的工作......除非你想将它重构为你自己的扩展方法,否则我会说如果有效的话就离开它。 / p>
视觉上,它不是那么混乱,所以这是一个加号。或者,您可以看到let关键字(基本上是子查询)是否会为您购买其他内容。
答案 5 :(得分:0)
lambda的长度根本不会打扰我。但是当我在select语句中指定一个值时,我会同意这种污垢的感觉。我会将初始化内容考虑在select语句下面的语句中。