No se puede convertir el tipo ‘System.Int32’ al tipo ‘System.Object’

publicado por: Anonymous

Estoy trabajando con Entity Framework con mvc y del lado del cliente he implementado un Select2 para esto he creado el siguiente modelo:

public class Select2
{
    public int id { get; set; }
    public string text { get; set; }
    public Object[] data { get; set; }
}

Las propiedades id y text son obligatorias para un select2, la propiedad data la he creado para ahi guardar todos los datos que extraigo en la consulta ya que anteriormente solo devolvía el id y el nombre que iban en las propiedades id y text entonces quiero agregar un array de objetos para guardar todas las demás columnas de mi consulta.

Utilizo este código:

[HttpGet]    
    public async Task<ActionResult> GetMesa(string q)
    {
        try
        {
            if (String.IsNullOrEmpty(q) || String.IsNullOrWhiteSpace(q))
            {
                return Json(new { respuesta="El filtro no puede ser nulo o un espacio en blanco /n" }, JsonRequestBehavior.AllowGet);
            }
            else
            {
                var items = await db.Mesa.Where(x => x.NombreMesa.ToLower().StartsWith(q.ToLower()))
                            .Select(x => new Select2()
                            {
                                id = x.MesaID,
                                text = x.NombreMesa,
                                data = new object[] { x.MesaID, x.NumeroMesa, x.NombreMesa, x.CapacidadMesa, x.AccionMesa, x.PisoMesa }
                            })
                            .ToListAsync();
                return Json(new { respuesta = "OK", items = items },JsonRequestBehavior.AllowGet);
            }
        }
        catch (Exception e)
        {
            return Json(new {respuesta = "MesasController => GetMesa n" + e.Message + e.InnerException}, JsonRequestBehavior.AllowGet);
        }
    }

El siguiente error me salta cuando asigno el valor a items:

No se puede convertir el tipo ‘System.Int32’ al tipo ‘System.Object’. LINQ to Entities solo admite la conversión de tipos de enumeración o primitivos de EDM.

¿Como puedo solucionarlo? o ¿tan solo debo utilizar otra forma?

solución

Cuando se pasa a construir el árbol de expresión lambda se intentará convertir los valores a un array de objetos, el cual a ser validado (ValidateAndAdjustCastTypes) detecta que ese tipo de conversión no está permitido.

Intenta pasando un método anónimo:

var items = await db.Mesa.Where(x => x.NombreMesa.ToLower().StartsWith(q.ToLower()))
    .Select(delegate(Mesa x) {
        return new Select2()
        {
            id = x.MesaID,
            text = x.NombreMesa,
            data = new object[] { x.MesaID, x.NumeroMesa, x.NombreMesa, x.CapacidadMesa, x.AccionMesa, x.PisoMesa }
        };
    })
    .ToListAsync();

Te dejo el enlace del método (ValidateAndAdjustCastTypes) que realiza la validación y arroja la excepción.

He replicado tu ejemplo y en efecto arroja una excepción tipo NotSupportedException:

Unable to cast the type ‘System.Int32’ to type ‘System.Object’. LINQ
to Entities only supports casting EDM primitive or enumeration types.

at
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.ValidateAndAdjustCastTypes(TypeUsage
toType, TypeUsage fromType, Type toClrType, Type fromClrType) at
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.GetCastTargetType(TypeUsage
fromType, Type toClrType, Type fromClrType, Boolean
preserveCastForDateTime) at
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.CreateCastExpression(DbExpression
source, Type toClrType, Type fromClrType) at
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.ConvertTranslator.TranslateUnary(ExpressionConverter
parent, UnaryExpression unary, DbExpression operand) at
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression
linq) at
System.Linq.Enumerable.WhereSelectEnumerableIterator’2.MoveNext() at
System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder.Internal.EnumerableValidator’3.Validate(IEnumerable’1
argument, String argumentName, Int32 expectedElementCount, Boolean
allowEmpty, Func’3 map, Func’2 collect, Func’3 deriveName) at
System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder.Internal.EnumerableValidator’3.Validate()
at
System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder.DbExpressionBuilder.CreateNewCollection(IEnumerable’1
elements) at
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.NewArrayInitTranslator.TypedTranslate(ExpressionConverter
parent, NewArrayExpression linq) at
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression
linq) at
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MemberInitTranslator.TypedTranslate(ExpressionConverter
parent, MemberInitExpression linq) at
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression
linq) at
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression
lambda, DbExpression input) at
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter
parent, MethodCallExpression call, DbExpression& source,
DbExpressionBinding& sourceBinding, DbExpression& lambda) at
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SelectTranslator.Translate(ExpressionConverter
parent, MethodCallExpression call) at
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter
parent, MethodCallExpression linq) at
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression
linq) at
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.Convert() at
System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable’1
forMergeOption)

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *