FireShock
FireShock

Reputation: 1122

"Specified cast is not valid" in LinqToSql query

Specified cast is not valid.

OrderItemState is enum.

IEnumerable<OrderItemState> states = ...;
IEnumerable<byte> stateIds = Enumerable.Cast<byte>(states);

List<OrderEntry> entries =
  (from m in dc.OrderItemMotions
   where stateIds.Contains(m.OrderItemStateId)
   select ...).ToList();

Why?

Part of StackTrace:

at System.Linq.Enumerable.d__b11.MoveNext() at System.Linq.Enumerable.<OfTypeIterator>d__aa1.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at System.Data.Linq.SqlClient.QueryConverter.VisitContains(Expression sequence, Expression value) at System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc) at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) at System.Data.Linq.SqlClient.QueryConverter.Visit(Expression node) at System.Data.Linq.SqlClient.QueryConverter.VisitWhere(Expression sequence, LambdaExpression predicate) at System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc) at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) at System.Data.Linq.SqlClient.QueryConverter.VisitWhere(Expression sequence, LambdaExpression predicate) at System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc) at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) at System.Data.Linq.SqlClient.QueryConverter.VisitGroupBy(Expression sequence, LambdaExpression keyLambda, LambdaExpression elemLambda, LambdaExpression resultSelector) at System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc) at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) at System.Data.Linq.SqlClient.QueryConverter.VisitJoin(Expression outerSequence, Expression innerSequence, LambdaExpression outerKeySelector, LambdaExpression innerKeySelector, LambdaExpression resultSelector) at System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc) at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) at System.Data.Linq.SqlClient.QueryConverter.ConvertOuter(Expression node) at System.Data.Linq.SqlClient.SqlProvider.BuildQuery(Expression query, SqlNodeAnnotations annotations) at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query) at System.Data.Linq.DataQuery1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)

Upvotes: 1

Views: 1204

Answers (3)

Dmitriy
Dmitriy

Reputation: 1972

Most likely one of your enum values contain a value that can't fit into a byte.

Assume this code:

IEnumerable<MyEnum> arr = new MyEnum[] { MyEnum.first, MyEnum.second };
var bytes = Enumerable.Cast<byte>(arr);
foreach (var b in bytes)
{
    Console.WriteLine(b);
}

It will work if:

enum MyEnum:byte { first = 120, second };

It won't work if:

enum MyEnum:long { first = 1204, second };

Upvotes: 0

Jackson Pope
Jackson Pope

Reputation: 14640

You can't cast an enum to a byte without data loss so the cast will fail (enum is an int under the hood).

But you can define an enum to use a byte under-the-hood if you only want values in the range 0-255 using:

public enum Values : byte { val1, val2};

See here: http://msdn.microsoft.com/en-us/library/sbbt4032.aspx

Upvotes: 2

Maarten
Maarten

Reputation: 22945

If the base-type of the enum is an int (which is default), you can cast the enum to an int.

If the base-type of the enum is a byte, you can cast the enum to a byte.

Upvotes: 0

Related Questions