2017-04-21 146 views
1

我有一个linq查询在我的aspnet核心应用程序返回更多的行,那么它应该。查询如下。如何做一个linq组

public List<csAutoComplete> GetAutoComplete(string Type, string filter) 
{ 
string[] GasCodesnotListed = { "F97", "F98", "F99" }; 
Model1 = from x in _context.TblGascodes 
    where ((x.GasCode.StartsWith("F13") || x.GasName.StartsWith("F13")) && 
      !GasCodesnotListed.Contains(x.FedclusterCode)) 
    orderby x.GasCode 
    group x by new csAutoComplete { ACCode = x.GasCode, ACName = x.GasName } into Alpha 
    select new csAutoComplete <=== (Is this the issue???) 
     { 
     ACCode = Alpha.Key.ACCode, 
     ACName = Alpha.Key.ACCode + " - " + Alpha.Key.ACName 
     }; 
return Model1.ToList(); 
} 

} 回报(7)导致

所以我粘贴到LINQ垫,并得到了结果,我预计(1)

string[] GasCodesnotListed = { "F97", "F98", "F99" }; 
TblGasCodes 
    .Where (
     x => 
     ((x.GasCode.StartsWith ("F13") || x.GasName.StartsWith ("F13")) && 
      !(GasCodesnotListed.Contains (x.GasCode)) 
     ) 
    ) 
    .OrderBy (x => x.GasCode) 
    .GroupBy (
     x => 
     new 
     { 
      ACCode = x.GasCode, 
      ACName = x.GasName 
     } 
    ) 
    .Select (
     Alpha => 
     new 
     { 
      ACCode = Alpha.Key.ACCode, 
      ACName = ((Alpha.Key.ACCode + " - ") + Alpha.Key.ACName) 
     } 
    ) 

唯一的区别似乎是在新的csAutoComplete。如果这是一个类定义,为什么这应该有所作为?我该如何解决这个问题。

+0

如果'csAutoComplete'没有覆盖'Equals',它将通过Object.ReferenceEquals()进行比较,而为了GroupBy的目的,匿名类型(如第二个示例中)是相同的,如果所有属性是相同的。我会使用匿名类型进行分组。 –

+0

当你说匿名类型时,我不明白这一点。你的意思是创建新变量并删除类? –

+1

在你的第二个版本中,你有'new ACCode = x.GasCode, ACName = x.GasName }' - 你正在创建一个匿名类型的实例。 –

回答

0

除非您不会覆盖EqualscsAutoComplete,GroupBy将使用Object.ReferenceEquals()或某些等价物比较csAutoComplete的实例。具有相同GasCodeGasName属性的两个实例将是两个独立的组密钥。如果你有七件物品进来,它们将分成七组,每组一件。

匿名类型不是这种情况。具有相同属性值的独立实例在GroupBy之间将被视为相等。如果你喜欢住在边缘或过载EqualscsAutoComplete -

var items = new[] { 0, 0 }.Select(n => new { x = n, y = n.ToString() }).ToArray(); 

var groups = items.GroupBy(x => x).ToArray(); 

// Not equal here! 
var aretheyequal = items[0] == items[1]; 

// But GroupBy isn't fooled: There's only one group 
var groupcount = groups.Length; 

使用您的匿名类型的一组密钥。根据我的经验(或者更准确地说,程序员通过不注意引入的更改而编写有趣的错误),可能会导致有趣的错误。我不想去那里。

因此,我认为你的GetAutoComplete方法是确定的,除了通过线组,我就改成这样:

group x by new { ACCode = x.GasCode, ACName = x.GasName } into Alpha 

后来参考ACCode = Alpha.Key.ACCode等应该不需要改变,因为属性名称是相同的。

+1

这是正确的,当它是对象的LINQ。不过,我认为'_context。TblGascodes'不是'IEnumerable',而是来自Entity Framework或LINQ to SQL的'IQueryable'。因此,表达式Model1作为一个整体将被转换为SQL,并且有或没有'csAutoComplete'的分组不应该有所作为。 @汤姆,你能谈谈这个吗? –

0

在你的代码,似乎是在GasCodesnotListed.Contains(一个着眼于FedclusterCode,另一个在GasCode)一个重要的区别:

where (x.GasCode.StartsWith ("F13") && !GasCodesnotListed.Contains (x.**FedclusterCode**)) 

... ...与

.Where (
    x => 
    (
     x.GasCode.StartsWith ("F13") && 
     !(GasCodesnotListed.Contains (x.**GasCode**)) 
    ) 
)