The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My work

  • My badges

  • Twitter Updates

  • My Flickr Stream

    NoRESInForms

    MPS_5159

    MPS_5158

    More Photos
  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,031 other followers

Entity Framework: simple solution for cryptic error message “System.NotSupportedException: Unable to create a constant value of type ‘System.Object’”

Posted by jpluimers on 2011/09/06

The drawback of using ORM layers is that often the error messages are very cryptic, and it takes some getting used to in order to find the (often deceptively) simple solution.

This case was an Entity Framework wrapper around a SQL Server database where the primary and foreign keys were all GUIDs, and some of the foreign keys were optional.

So the generated model has a mixed use of Guid? and Guid data types.

Below is the full stack trace, but here is the exception class and message:

System.NotSupportedException: Unable to create a constant value of type ‘System.Object’. Only primitive types (‘such as Int32, String, and Guid’) are supported in this context.

The exception is caused by a piece of code like this:

        public static long CountChildren(ParentEntity parentEntity)
        {
            using (EntitiesObjectContext objectContext = new EntitiesObjectContext())
            {
                Guid? parentId = parentEntity.ID;

                if (null == parentId)
                    throw new ArgumentNullException("parentEntity.Id");

                IQueryable<ChildEntity> ChildEntitys =
                    from content in objectContext.ChildEntity
                    where content.ParentID.Equals(parentId)
                    select content;

                long result = ChildEntitys.Count(); // BOOM!

                return result;
            }
        }

The stack trace at the end of this post contains a truckload of ExpressionConverter lines. Since the LINQ expression contained only one WHERE clause, the mentioning of the list of primitive types in the message (Int32, String, and Guid) made me change the code into the one below.

Note that it would have been much harder if I had a more complex where clause: the exception message does not indicate which portion of the expression, or which source data type it trying to generate a constant from.

        public static long CountChildren(ParentEntity parentEntity)
        {
            using (EntitiesObjectContext objectContext = new EntitiesObjectContext())
            {
                Guid? parentId = parentEntity.ID;

                if (null == parentId)
                    throw new ArgumentNullException("parentEntity.Id");

                IQueryable<ChildEntity> ChildEntitys =
                    from content in objectContext.ChildEntity
                    where content.ParentID.Equals(parentId.Value)
                    select content;

                long result = ChildEntitys.Count();

                return result;
            }
        }

It immediately worked.

But it would have been so much easier if the exception message tried to tell me from which type it was trying to generate a constant value.

System.NotSupportedException: Unable to create a constant value of type 'System.Object'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.
   at System.Data.Objects.ELinq.ExpressionConverter.ConstantTranslator.TypedTranslate(ExpressionConverter parent, ConstantExpression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.EqualsTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input)
   at System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input, DbExpressionBinding& binding)
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression& source, DbExpressionBinding& sourceBinding, DbExpression& lambda)
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.AggregateTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.Convert()
   at System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
   at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
   at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
   at System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__3[TResult](IEnumerable`1 sequence)
   at System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
   at System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression)
   at System.Linq.Queryable.Count[TSource](IQueryable`1 source)

–jeroen

3 Responses to “Entity Framework: simple solution for cryptic error message “System.NotSupportedException: Unable to create a constant value of type ‘System.Object’””

  1. Erik van Appeldoorn said

    Hi Jeroen

    Why don’t you use the regular strongly typed version: where content.ParentID.== parentId.Value where there is compiler checking?

  2. Craig said

    I’m working on a wiki of how to resolve EF error messages. Contributions welcome!

    http://social.technet.microsoft.com/wiki/contents/articles/3908.aspx

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

Join 1,031 other followers

%d bloggers like this: