2012-11-05 56 views
2

我用下面的IEqualityComparer從公司名稱脫衣特殊字符查找記錄如下:使用的IEqualityComparer比較之前

public class CompanyNameIgnoringSpaces : IEqualityComparer<LeadGridViewModel> 
    { 
     public bool Equals(LeadGridViewModel x, LeadGridViewModel y) 
     { 
      var delimiters = new[] {' ', '-', '*', '&', '!'}; 
      return delimiters.Aggregate(x.CompanyName ?? String.Empty, (c1, c2) => c1.Replace(c2, '\0')) 
       == delimiters.Aggregate(y.CompanyName ?? String.Empty, (c1, c2) => c1.Replace(c2, '\0')); 
     } 

     public int GetHashCode(LeadGridViewModel obj) 
     { 
      var delimiters = new[] {' ', '-', '*', '&', '!'}; 
      return delimiters.Aggregate(obj.CompanyName ?? String.Empty, (c1, c2) => c1.Replace(c2, '\0')).GetHashCode(); 
     } 
    } 

爲了運行查詢時調用此,我用的是以下幾點:

var results = result 
        .GroupBy(c => c, new CompanyNameIgnoringSpaces()) 
        .Select(g => new LeadGridViewModel 
        { 
         LeadId = g.First().LeadId, 
         Qty = g.Count(), 
         CompanyName = g.Key.CompanyName, 
        }).OrderByDescending(x => x.Qty).ThenBy(x => x.CompanyName).ToList(); 

如何在LINQ查詢中使用此比較器以查找與輸入字符串(公司名稱)匹配的所有記錄?

例如:

public List<LeadGridViewModel> AllByName(string name, int company) 
     { 

      var result = (from t1 in db.Leads 
          where 
           t1.Company_ID == company && t1.Company_Name == name... 

因此,而不是使用t1.Company_Name ==名字,我想用用相等比較這包括特殊字符替換。

回答

1
  1. 在linqToDatabase查詢中使用的的IEqualityComparer: 除非你可以封裝邏輯的形式提供程序可以翻譯那麼這將必須在本地完成。從你遇到這個問題的路線,我認爲提供者無法處理它。因此,我們可以做到在本地端如下:

    1. 把它全部:

      var results = result.ToArray() 
           .GroupBy(c => c, new CompanyNameIgnoringSpaces()) 
           .Select(g => new LeadGridViewModel 
           { 
            LeadId = g.First().LeadId, 
            Qty = g.Count(), 
            CompanyName = g.Key.CompanyName, 
           }).OrderByDescending(x => x.Qty).ThenBy(x => x.CompanyName).ToList(); 
      
    2. ToLookup()

      var results = result 
           .ToLookup(c => c, new CompanyNameIgnoringSpaces()) 
           .Select(g => new LeadGridViewModel 
           { 
            LeadId = g.First().LeadId, 
            Qty = g.Count(), 
            CompanyName = g.Key.CompanyName, 
           }).OrderByDescending(x => x.Qty).ThenBy(x => x.CompanyName).ToList(); 
      
    3. 流的結果

      var results = result.AsEnumerable() 
           .GroupBy(c => c, new CompanyNameIgnoringSpaces()) 
           .Select(g => new LeadGridViewModel 
           { 
            LeadId = g.First().LeadId, 
            Qty = g.Count(), 
            CompanyName = g.Key.CompanyName, 
           }).OrderByDescending(x => x.Qty).ThenBy(x => x.CompanyName).ToList(); 
      

    注意:sql的大多數變體都有替換函數,因此您可以將替換代碼硬編碼到表達式中,因此可以在服務器端執行此操作。如果你希望它是可重複使用的,你會希望像下面這樣:

    private static Expression<Func<LeadGridViewModel,String>> leadGridTransform = 
        (lead) => lead.CompanyName == null ? "", lead.CompanyName.Replace(' ','\0').Replace.... ; 
    

    你然後能在可查詢表達式中使用:

    var results = result.GroupBy(leadGridTransform).... 
    

    三元運算符用在這裏,因爲它避免了昂貴的服務器端合併操作。

  2. 查找特定字符串的所有記錄: 在這裏,您確實想要顛倒比較並查找與給定字符串相同的所有字符串,然後查詢其中包含的公司名稱。所以假設db。信息是LeadGridViewModel的表,所以我們可以用比較器

    1. 隱反轉:

      public List<LeadGridViewModel> AllByName(string name, int company) 
      { 
          var comparer = new CompanyNameIgnoringSpaces(); 
          var group = db.Leads.Select(lead => new LeadGridViewModel 
                 { CompanyName = lead.CompanyName }) 
               .AsEnumerable() 
               .Where(lead => comparer.Equals(name, lead.CompanyName) 
               .ToArray(); 
      
          var result = db.Leads.Where(lead => lead.Company_ID == company) 
               .Where(lead => group.Contains(lead.CompanyName))... 
      
    2. 明確反轉:

      private var delimiters = new[] {' ', '-', '*', '&', '!'}; 
      public List<LeadGridViewModel> AllByName(string name, int company) 
      { 
          var atomicName = name.Trim().Split(delimiters); 
          IEnumerable<String> permutations = atomicName.Aggregate(
             new String[] {""}, 
             (accumulate,atom) => atom == "" ? accumulate.Join(
              delimiters,str => true,chr => true,(str,chr) => str + atom + chr.ToString()) : accumelate) 
            .ToArray(); 
      
          var result = db.Leads.Where(lead => lead.Company_ID == company) 
               .Where(lead => permutations.Contains(lead.CompanyName))... 
      

注:對於這兩種方法都有反轉比較有自己的限制。在第一個實現中,數據庫越大,構建可用分組的速度越慢。對於第二種實現,這個名稱的分隔符越多,建立排列所需的時間就越多(指數級)。如果你替代硬編碼,那麼這可以在服務器端完成,從而避免這些限制。

1

你不能。用於調用IEqualityComparison的代碼(甚至是其中使用的代碼)不能轉換爲SQL查詢,因爲IEqualityComparison中的代碼是編譯的,而不是使用Expression對象編譯的。

相關問題