2014-06-30 24 views
0

我今天面对这种情况,无法在网上找到我想要的。店内变量linq

看看这段代码,

myCollection.Select(g => new ReportLine 
{ 
    cds = (sectors.FirstOrDefault(s => s.SECT_CODE.Equals(g.Contract.Station.Sector.SECT_CODE)) != null ? 
       sectors.FirstOrDefault(s => s.SECT_CODE.Equals(g.Contract.Station.Sector.SECT_CODE)).USER != null? 
        sectors.FirstOrDefault(s => s.SECT_CODE.Equals(g.Contract.Station.Sector.SECT_CODE)).USER.USER_FIRSTNAME : "": "") 
           + " " + 
      (sectors.FirstOrDefault(s => s.SECT_CODE.Equals(g.Contract.Station.Sector.SECT_CODE)) != null ? 
       sectors.Where(s => s.SECT_CODE.Equals(g.Contract.Station.Sector.SECT_CODE)).FirstOrDefault().USER != null? 
        sectors.Where(s => s.SECT_CODE.Equals(g.Contract.Station.Sector.SECT_CODE)).FirstOrDefault().USER.LASTNAME : "" : "") 
}); 

基本上“MyCollection的”是一种深深的类的列表,并申请进入它提取的姓氏和名字,并把它们在其他类而如果检查有没有空值。

君不见实现,我查了同样的事情,6次:

sectors.FirstOrDefault(s => s.SECT_CODE.Equals(g.Contract.Station.Sector.SECT_CODE)) 

(可能是痛苦的性能)

难道一个方式中存在“存储”在LINQ表达式中的价值?是这样的:

myCollection.Select(g => new ReportLine 
{ 
    cds = ((var tmp =sectors.FirstOrDefault(s => s.SECT_CODE.Equals(g.Contract.Station.Sector.SECT_CODE))) != null ? 
       tmp.USER != null? 
        tmp.USER.USER_FIRSTNAME + "" + tmp.USER.LASTNAME: "": "") 
}); 

回答

2

试试这个:

myCollection.Select(g => { 
    var sect_code = g.Contract.Station.Sector.SECT_CODE; 
    var sector = sectors.FirstOrDefault(s => s.SECT_CODE.Equals(sect_code)); 
    var firstName = sector != null ? 
     (sector.USER != null ? sector.USER.USER_FIRSTNAME: "") : 
     ""; 
    var lastName = sector != null ? 
     (sector.USER != null ? sector.USER.LASTNAME : "") : 
     ""; 
    return new ReportLine 
    { 
     cds = string.Format("{0} {1}", firstName, lastName) 
    }; 
}); 
+0

很确定EF无法正确翻译。 – Servy

+0

@Servy,为什么不呢?那是标准的linq?你的意思是因为它不能查找'合约',然后'站'和'部门'?如果你问我那不是上述问题的linq,而是EF,如果使用的话,并且他在表达式中有一个真正的嵌套结构。 –

2

我想你也许会不得不更改为长手LINQ做到这一点,但您可以使用LINQ's let clause在一个表达式的中间变量赋值。

+0

什么是长手LINQ?我看到使用流利的语法没有问题。 –

+0

有关示例,请参阅答案中的链接。这是一种更详细的,SQL-ish方式来编写相同的表达式。 –

+0

我知道常规的linq语法和let子句,我只是认为在写长篇LINQ时你的意思是别的,因为我从来没有听说过。但你为什么认为他必须改变语法? –

-1

您可以将Select语句中的逻辑提取为单独的方法,并在Select语句中调用该语句?

喜欢的东西...

private string Foo(Sector input) 
{ 
    var tmp = g.SECT_CODE.Equals etc etc 
    return tmp.USER != null ? etc etc 
} 

...

myCollection.Select(g => Foo(g)) 
+0

如果您进行此更改,则EF将无法解析代码以将其转换为SQL。 – Servy

+0

是否指定这是一个SQL调用? – PulseLab

+0

这个问题被标记为EF。 – Servy

0

myCollection.Select(G => { 变种临时= sectors.FirstOrDefault(); ...

return new ReportLine(){..};

} )

0

这应该是你在找什么:

myCollection.Select(g => new ReportLine 
{ 
    cds = (from s in sectors 
      where s.SECT_CODE.Equals(g.Contract.Station.Sector.SECT_CODE) && s.USER != null 
      select string.Format("{0} {1}", s.USER.USER_FIRSTNAME, s.USER.USER_LASTNAME)).FirstOrDefault() ?? " " 
});