2012-02-20 78 views
1
private void InsertLinks(IEnumerable<string> urls) 
    { 
     EntityDataModelContext context = DataContext.GetDataContext(); 
     foreach (string url in urls) 
     { 
      string url1 = url; 
      if (context.Links.Any(l => MatchUrlHash(l.UrlHash, url1))) 
      { 
       continue; 
      } 
      Link link = new Link 
      { 
       Url = url, 
      }; 
      context.Links.AddObject(link); 
     } 
     context.SaveChanges(); 
    } 

    private bool MatchUrlHash(long urlHash, string url) 
    { 
     SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider(); 
     byte[] encoded = Encoding.ASCII.GetBytes(url); 
     byte[] checksum = sha.ComputeHash(encoded); 
     long hash = BitConverter.ToInt64(checksum, 0); 
     return urlHash == hash; 
    } 

如何將此查詢轉換爲仍能正常執行並且不會丟失任何NotSupportedException的東西?LINQ To Entities以及如何使這個簡單的查詢工作

+1

順便說一句,叫處置或更好地利用'using'語句的上下文實例。 – 2012-02-20 19:32:09

回答

4

EF不知道如何使用MatchUrlHash構建SQL查詢。您可以事先準備好網址哈希值並使用常規樣式比較,==

private long CreateUrlHash(string url) 
{ 
    SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider(); 
    byte[] encoded = Encoding.ASCII.GetBytes(url); 
    byte[] checksum = sha.ComputeHash(encoded); 
    return BitConverter.ToInt64(checksum, 0); 
} 

// ... 
long urlHash = CreateUrlHash(url); 
if (context.Links.Any(l => l.UrlHash == urlHash)) 
{ 
    continue; 
} 
+0

順便說一句也是效率更高 – BrokenGlass 2012-02-20 19:40:26

+0

爲什麼EF不能處理這樣的查詢?據我記得'L2SQL'可以。 – bevacqua 2012-02-20 19:41:00

+1

@Nico - SQL查詢將包含您的MatchUrlHash方法嗎? L2S或EF如何知道如何將該方法轉換爲SQL? – 2012-02-20 19:50:29

0

您無法將您的MatchUrlHash傳遞給sql實體提供者。因此,要麼拉的所有記錄,然後運行自定義邏輯context.Links.ToList().Any(l=>MatchUrlHash(l.UrlHash, url1))

羅..只是重寫了整個事情

private void InsertLinks(IEnumerable<string> urls) 
    { 
     EntityDataModelContext context = DataContext.GetDataContext(); 

     var withhashes=urls.Select(u=>new {Url=u,Hash= Hash(u)}); 
     withhashes.Where(h=>!context.Links.Any(l=>l.UrlHash==h.Hash)) 
      .ToList() 
      .ForEach(h=> { 
      context.Links.Add(new Link(){ 
        Url = h.Url 
        }); 
       }); 

      context.SaveChanges(); 



    } 

    private bool Hash(string url) 
    { 
     SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider(); 
     byte[] encoded = Encoding.ASCII.GetBytes(url); 
     byte[] checksum = sha.ComputeHash(encoded); 
     long hash = BitConverter.ToInt64(checksum, 0); 
     return hash; 
    }