LINQ To Entities以及如何使这个简单的查询工作

时间:2012-02-20 19:28:11

标签: c# linq entity-framework

    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的内容?

2 个答案:

答案 0 :(得分:4)

EF不知道如何使用MatchUrlHash构建SQL查询。您可以事先准备好url hash并使用常规样式比较==

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;
}

答案 1 :(得分:0)

您无法将MatchUrlHash传递给sql实体提供程序。因此,要么拉出所有记录,然后运行自定义逻辑context.Links.ToList().Any(l=>MatchUrlHash(l.UrlHash, url1))

nah ..只是改写了整个事情

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;
   }