0

I need to check if my byte array contains string in LinQ Where() method. At the moment I have something like:

public static bool ContainsSequence(byte[] toSearch, byte[] toFind)
{
    for (var i = 0; i + toFind.Length < toSearch.Length; i++)
    {
        var allSame = true;
        for (var j = 0; j < toFind.Length; j++)
        {
            if (toSearch[i + j] != toFind[j])
            {
                allSame = false;
                break;
            }
        }

        if (allSame)
        {
            return true;
        }
    }

    return false;
}
var data = MyCollection.Where(x => ContainsSequence(x.ByteArrayValue, myStringToByteArray);

but I'm getting exception:

LINQ to Entities does not recognize the method ContainsSequence

I've read somewhere that I can rewrite ContainsSequence method to Linq.Extensions.Extension but I have no idea how. Can someone direct me to a solution?

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
d3st1ny
  • 75
  • 1
  • 13
  • Why not just fetch the entire collection by doing `MyCollection.AsEnumerable()` and then doing `.Where()` on that? Unless your collection is extremely large then doing it in memory shouldn't be a problem. – stelioslogothetis Jul 10 '17 at 07:08
  • Did you mean: var data = MyCollection.AsEnumerable().Where(x => ContainsSequence(x.ByteArrayValue, myStringToByteArray); //? I'm getting null reference exception when I do this – d3st1ny Jul 10 '17 at 07:12
  • This should work: `var data = MyCollection.AsEnumerable().Where(x => ContainsSequence(x.ByteArrayValue, myStringToByteArray);` – stelioslogothetis Jul 10 '17 at 07:13
  • what type is `MyCollection`? – Lei Yang Jul 10 '17 at 07:15
  • It's DataSet from my Entity Framework Database. Collection is set of data which I want to load to memory. I didn't realise that is important. – d3st1ny Jul 10 '17 at 07:19
  • suggest simplify your `ContainsSequence` by using Linq's `Skip` and `Take` and then `SequenceEqual` – Lei Yang Jul 10 '17 at 07:23
  • Can you show us some sample data for `ByteArrayValue` and `myStringToByteArray`? – mjwills Jul 10 '17 at 07:41
  • If your two sequences are the same then you will return false. Is this by design as it could lead to unexpected behaviour. – Scrobi Jul 10 '17 at 08:04

2 Answers2

3

EntityFramework only allows you to use a limited selection of LINQ methods, because, unless you explicitly tell it otherwise, EF doesn't execute them in memory, but converts them into a query and has the SQL provider do it instead. If you want to use your own custom method you will have to do the following:

var data = MyCollection.AsEnumerable().Where(x => ContainsSequence(x.ByteArrayValue, myStringToByteArray);

What we are doing here is we are casting the collection (which should be a DbSet or IQueryable) into an IEnumerable, on which we can use the custom method.

Be advised however, this has the side effect of loading the entire set into memory. This shouldn't be a problem unless you're dealing with very large amounts of data, but it is something to keep in mind.

You can read more about AsEnumerable() and exactly what it does and when to use it here.

stelioslogothetis
  • 9,371
  • 3
  • 28
  • 53
0

try this:

foreach (var item in MyCollection.ToArray())
{
   var data = item.Where(x => x.ContainsSequence(x.ByteArrayValue, myStringToByteArray));
}
pitersmx
  • 935
  • 8
  • 27