O Linq Query continua lançando “Não é possível criar um valor constante do tipo System.Object…”, por quê?

94

A seguir está o exemplo 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();
        }
    }

não consigo entender o que estou fazendo de errado. Eu continuo recebendo "Não é possível criar um valor constante do tipo 'System.Object'. Somente tipos primitivos ('como Int32, String e Guid') são suportados neste contexto."

Neel
fonte

Respostas:

232

Use == em vez de igual:

where t.CustID == custIdToQuery

Se os tipos estiverem incorretos, você pode descobrir que ele não compila.

Mark Byers
fonte
10
Você pode explicar a diferença entre "t.CustID == custIdToQuery" e "t.CustID.Equals (custIdToQuery)". obrigado antecipadamente
Neel
2
@Neel Dê uma olhada nesta pergunta para obter uma explicação sobre a diferença entre ==e .Equals(): stackoverflow.com/questions/814878/…
Alex
A lógica da solução de 2011 funcionou em 2018! Impressionante Worthful!
Yeshwant Mudholkar de
29

Eu tive o mesmo problema com um int anulável. Usar == em vez disso funciona bem, mas se você quiser usar .Equals, você pode compará-lo ao valor da variável anulável, então

where t.CustID.Value.Equals(custIdToQuery)
Kloarubeek
fonte
9

Eu tive o mesmo problema quando estava tentando fazer .Equals com um decimal anulável. Usar == em vez disso funciona bem. Eu acho que isso é porque ele não está tentando corresponder ao "tipo" exato de decimal? para decimal.

Dave Stuart
fonte
4
Lembre-se de que isso está no contexto de um IQueryable, portanto, não é compilado em código C # regular. Torna-se uma expressão que é passada para um provedor de consulta. Esse provedor de consulta pode fazer o que quiser com a consulta e pode tratar Equalse fazer ==o mesmo ou não.
Servy de
Eu costumava .Equal()comparar Int32?com Int32. Uma vez que Int32?é suposto conter Int32e null, pensei que funcionaria. Mas isso não aconteceu. ==funcionou.
matriz
1

Eu estava enfrentando o mesmo problema e estava comparando o objeto de coleção "User"com o tipo de dados inteiro "userid"( x.User.Equals(userid))

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

e a consulta correta é x.UserId.Equals(userid)

from user in myshop.UserPermissions.Where(x => x.IsDeleted == false && x.UserId.Equals(userid))
Satish Kumar Sonker
fonte
Este é um problema diferente, você está comparando maçãs e laranjas.
Lasse V. Karlsen
como é diferente. enquanto eu enfrentei o mesmo problema. acabei de postar esta resposta para referência apenas para outros.
Satish Kumar sonker
0

No meu caso, mudei a chamada direta de (sender as Button).Textpara indireta usando um var temp, funcionou. código de trabalho:

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 com bugs:

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
fonte