1

I have a LINQ query to get data from my database:

query.Select(b => b.BooleanValue.Value).Distinct().ToArray(); 

This query gives me the error

Linq Cannot implicitly convert type 'bool[]' to 'object[]'.

I get the same error with a decimal value but with a text value it all works fine. I searched all over the internet and I only found people that are having problems with object to bool.

Do you know how to convert (within a LINQ select) decimal to object?

Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170
jfamvg
  • 237
  • 3
  • 10
  • What linq provider do you use? – hazzik Apr 25 '14 at 12:49
  • Shouldn't that have `b => b.BooleanValue.GetValueOrDefault()`? Or are you sure every bool is going to have a value? – Brad Christie Apr 25 '14 at 12:51
  • No it is a nullable bool – jfamvg Apr 25 '14 at 12:57
  • What's the point of taking distinct booleans? Since you are taking the `Value` of `Nullable`, you know the values are non-null. Therefore you're bound to get an array of at most two elements (you get zero elements when `query` is empty, one element when all boolean values are the same, and two items when both `true` and `false` are present). Are you trying to check some special condition related to the mixture of boolean flags (e.g. "some flags are `true`" or "all flags are the same"?) – Sergey Kalinichenko Apr 25 '14 at 12:58
  • I am trying to to the same with a decimal, get the same results – jfamvg Apr 25 '14 at 13:08
  • 1
    @jfamvg: And when `b.BooleanValue = null` you're going to get an exception in that `.Select()` since `.Value` won't exist. – Brad Christie Apr 25 '14 at 14:05

3 Answers3

9

You have a LINQ-to-Entities query which you wish to execute on the server and get the result back as an array of objects. The query on the server gives a sequence of distinct values of value type.

So what we're going to do is execute as much of the query on the server as possible, then turn the results into an ordinary sequence on the client, and then box the values on the client. So:

object[] results = query
  .Select(b => b.BooleanValue.Value) // on the server
  .Distinct() // on the server
  .AsEnumerable() // now we're on the client
  .Cast<object>() // box each value to object on the client
  .ToArray(); // put the results into an array of objects on the client

Done.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
5
query
  .Select(b => b.BooleanValue.Value)
  .Distinct()
  .Cast<object>()
  .ToArray();

You probably need to do this:

query
  .Select(b => b.BooleanValue.Value)
  .Distinct()
  // execute query
  .AsEnumerable()
  // cast in memory
  .Cast<object>()
  .ToArray();

Only arrays of reference types are co-variant. This is a controversial feature.

Community
  • 1
  • 1
Stefan Steinegger
  • 63,782
  • 15
  • 129
  • 193
  • or even just `ToArray()` instead of the `Cast` call. – Rawling Apr 25 '14 at 12:52
  • @Rawling - wouldn't `ToArray` require an `IEnumerable` as the input? – D Stanley Apr 25 '14 at 12:56
  • I added the .Cast() but I get the error: Unable to cast the type 'System.Decimal' to type 'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types. – jfamvg Apr 25 '14 at 12:56
  • Yes, true. I just try to avoid passing generic arguments on methods like ToArray or Select, because they normally don't need any. – Stefan Steinegger Apr 25 '14 at 12:56
  • @DStanley Fair point; in older versions of .NET (before covariance) that wouldn't work. – Rawling Apr 25 '14 at 12:57
  • @Rawling: No, it won't work in newer versions of the CLR either. Covariance requires that both type arguments be reference types. – Eric Lippert Apr 25 '14 at 12:59
  • I changed my query but I get the error: Unable to cast the type 'System.Decimal' to type 'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types. I am using EF6. – jfamvg Apr 25 '14 at 13:04
  • 2
    To clarify your last point, the controversial bit is that the feature exists at all, not that it exists only for reference types. (In fact, there is some covariance on value type arrays; the CLR will allow `int[]` to `uint[]` conversion to succeed.) – Eric Lippert Apr 25 '14 at 13:10
  • 1
    Use `AsEnumerable`, not `ToArray`, to bring an on-server query into the client. – Eric Lippert Apr 25 '14 at 13:10
0
query.Select(b => (object)b.BooleanValue.Value).Distinct().ToArray();

or

query.Select(b => b.BooleanValue.Value).Distinct().Cast<object>().ToArray();
Rawling
  • 49,248
  • 7
  • 89
  • 127
Nuri YILMAZ
  • 4,291
  • 5
  • 37
  • 43