LINQ To Entities и как заставить этот простой запрос работать - PullRequest
1 голос
/ 20 февраля 2012
    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 s?

Ответы [ 2 ]

4 голосов
/ 20 февраля 2012

EF не знает, как построить SQL-запрос с MatchUrlHash.Вы можете просто подготовить URL-хэш заранее и использовать обычное сравнение стилей, ==.

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 голосов
/ 20 февраля 2012

Вы не можете передать свой 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;
   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...