2013-01-15 18 views
3

我想要做的就是正确声明var place,所以一旦我到达foreach循环,它仍然在范围内。我假设我需要在connectionsif声明之前声明它。这是一个正确的假设,如果是的话,我该如何申报?谢谢!正确声明匿名类型为数组以正确保持作用域

using (var db = new DataClasses1DataContext()) 
     { 
      if (connections == "Connections") 
      { 
       var place = (from v in db.pdx_aparts 
          where v.Latitude != null && v.Region == region && v.WD_Connect >= 1 
          select new 
          { 
           locName = v.Apartment_complex.Trim().Replace(@"""", ""), 
           latitude = v.Latitude, 
           longitude = v.Longitude 
          }).Distinct().ToArray(); 
      } 
      else 
      { 
       var place = (from v in db.pdx_aparts 
          where v.Latitude != null && v.Region == region && ((v.WD_Connect == null) || (v.WD_Connect == 0)) 
          select new 
          { 
           locName = v.Apartment_complex.Trim().Replace(@"""", ""), 
           latitude = v.Latitude, 
           longitude = v.Longitude 
          }).Distinct().ToArray(); 

      } 

      foreach (var result in place) 
      .... 
+1

你可以在'if'折叠成'where',而是和只有一个查询?我不认为你可以在分配给它之前声明一个匿名类型的变量。 – Blorgbeard

+0

@Blorgbeard可能会阻止SQL Server使用索引。取决于OPs模式。 – usr

+0

@usr我正在使用索引。感谢您注意 –

回答

7

你可以用一个单一的入口,其价值以后忽略创建数组:

// Note: names *and types* must match the ones you use later on. 
var place = new[] { new { locName = "", latitude = 0.0, longitude = 0.0 } }; 
if (connections = "Connections") 
{ 
    // Note: not a variable declaration 
    place = ...; 
} 
else 
{ 
    place = ...; 
} 

这工作,因为每次使用使用性质相同名称和类型匿名类型,以相同的顺序,将使用相同的具体类型。

我认为这将是更好地使代码,它需要尽管部分不同:

var query = v.db.pdx_aparts.Where(v => v.Latitude != null && v.Region == region); 
query = connections == "Connections" 
    ? query.Where(v => v.WD_Connect >= 1) 
    : query.Where(v => v.WD_Connect == null || v.WD_Connect == 0); 
var places = query.Select(v => new 
          { 
           locName = v.Apartment_complex 
             .Trim() 
             .Replace("\"", ""), 
           latitude = v.Latitude, 
           longitude = v.Longitude 
          }) 
        .Distinct() 
        .ToArray(); 

这更容易告诉依赖于该部分connections value是查询处理WD_Connect的部分。

+1

+1。提前定义类型的巧妙技巧。 –

2

您可以将if转换为?:

var place = connections == "Connections" ? monsterQuery1 : monsterQuery2; 

我不认为这是一个很好的解决方案,因为您的查询太大(不可读)。

如果您引入了命名的类而不是匿名类型,那将会好得多。 R#为你在“灯泡菜单”重构中做到了这一点。

+1

更改为使用命名类本身不会*减少大查询。有更好的方法来处理那个不需要命名类的部分。 –

+1

@JonSkeet我同意,你的回答比较好。更全面。 – usr

1

你可以只使用1个查询,因为它们是几乎相同的,只是添加额外的条件在where子句中

var place = (from v in db.pdx_aparts 
      where v.Latitude != null && v.Region == region 
      && connections == "Connections" 
      ? v.WD_Connect >= 1 
      : ((v.WD_Connect == null) || (v.WD_Connect == 0)) 
      select new 
      { 
       locName = v.Apartment_complex.Trim().Replace(@"""", ""), 
       latitude = v.Latitude, 
       longitude = v.Longitude 
      }).Distinct().ToArray(); 


foreach (var result in place) 
.... 
+1

这可能会阻止SQL Server使用索引。取决于OPs模式。它会执行,但性能配置文件可能会更糟。 – usr