Linq Query sigue arrojando "No se puede crear un valor constante de tipo System.Object ...", ¿por qué?

94

El siguiente es el ejemplo de código:

private void loadCustomer(int custIdToQuery) 
    {
        var dbContext = new SampleDB();
        try
        {
            var customerContext = from t in dbContext.tblCustomers      // keeps throwing:
                                   where t.CustID.Equals(custIdToQuery) // Unable to create a constant value of type 'System.Object'. 
                                   select new                           // Only primitive types ('such as Int32, String, and Guid') 
                                   {                                    // are supported in this context.
                                       branchId = t.CustomerBranchID,   //
                                       branchName = t.BranchName        //
                                   };                                   //

            if (customerContext.ToList().Count() < 1) //Already Tried customerContext.Any()
            {
                lstbCustomers.DataSource = customerContext;
                lstbCustomers.DisplayMember = "branchName";
                lstbCustomers.ValueMember = "branchId";
            }
            else
            {
                lstbCustomers.Items.Add("There are no branches defined for the selected customer.");
                lstbCustomers.Refresh();
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        finally
        {
            dbContext.Dispose();
        }
    }

No puedo entender qué estoy haciendo mal. Sigo recibiendo "No se puede crear un valor constante de tipo 'System.Object'. Solo los tipos primitivos ('como Int32, String y Guid') son compatibles en este contexto".

Neel
fuente

Respuestas:

232

Use == en lugar de Equals:

where t.CustID == custIdToQuery

Si los tipos son incorrectos, es posible que esto no se compile.

Mark Byers
fuente
10
¿Puede explicar la diferencia entre "t.CustID == custIdToQuery" y "t.CustID.Equals (custIdToQuery)"? gracias de antemano
Neel
2
@Neel Eche un vistazo a esta pregunta para obtener una explicación sobre la diferencia entre ==y .Equals(): stackoverflow.com/questions/814878/…
Alex
¡La lógica de la solución 2011 funcionó en 2018! Impresionante digno!
Yeshwant Mudholkar
29

Tuve el mismo problema con un int que acepta valores NULL. Usar == en su lugar funciona bien, pero si desea usar .Equals, puede compararlo con el valor de la variable anulable, por lo que

where t.CustID.Value.Equals(custIdToQuery)
kloarubeek
fuente
9

Tuve el mismo problema cuando intentaba hacer .Equals con un decimal anulable. Usar == en su lugar funciona bien. Supongo que esto se debe a que no está tratando de coincidir con el "tipo" exacto de decimal. a decimal.

Dave Stuart
fuente
4
Tenga en cuenta que esto está en el contexto de un IQueryable, por lo que no está compilado en el código C # normal. Se convierte en una expresión que se pasa a un proveedor de consultas. Eso proveedor de consulta se puede hacer lo que quiera con la consulta, y puede manejar Equalsy ==el mismo o no.
Servicio
Solía .Equal()comparar Int32?con Int32. Dado que Int32?se supone que contiene Int32y null, pensé que funcionaría. Pero no fue así. ==trabajó.
matriz
1

Me enfrenté al mismo problema y estaba comparando el objeto de colección "User"con el tipo de datos entero "userid"( x.User.Equals(userid))

from user in myshop.UserPermissions.Where(x => x.IsDeleted == false && x.User.Equals(userid))

y la consulta correcta es x.UserId.Equals(userid)

from user in myshop.UserPermissions.Where(x => x.IsDeleted == false && x.UserId.Equals(userid))
Satish Kumar sonker
fuente
Este es un problema diferente, estás comparando manzanas y naranjas.
Lasse V. Karlsen
cómo es diferente. mientras me he enfrentado al mismo problema. Solo publico esta respuesta como referencia solo para otros.
Satish Kumar sonker
0

En mi caso, cambié la llamada directa de (sender as Button).Texta llamada indirecta usando una var temporal, funcionó. código de trabajo:

private void onTopAccBtnClick(object sender, EventArgs e)
    {
        var name = (sender as Button).Text;
        accountBindingSource.Position =
                    accountBindingSource.IndexOf(_dataService.Db.Accounts.First(ac => ac.AccountName == name));
        accountBindingSource_CurrentChanged(sender, e);
    }

código buggy:

private void onTopAccBtnClick(object sender, EventArgs e)
    {
        accountBindingSource.Position =
                    accountBindingSource.IndexOf(_dataService.Db.Accounts.First(ac => ac.AccountName == (sender as Button).Text));
        accountBindingSource_CurrentChanged(sender, e);
    }
vaheeds
fuente