Linq Query wirft immer wieder die Meldung "Es kann kein konstanter Wert vom Typ System.Object ... erstellt werden". Warum?

94

Das folgende ist das Codebeispiel:

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();
        }
    }

Ich kann nicht verstehen, was ich falsch mache. Ich erhalte immer wieder die Meldung "Es kann kein konstanter Wert vom Typ 'System.Object' erstellt werden. In diesem Zusammenhang werden nur primitive Typen ('wie Int32, String und Guid') unterstützt."

Neel
quelle

Antworten:

232

Verwenden Sie == anstelle von Equals:

where t.CustID == custIdToQuery

Wenn die Typen falsch sind, stellen Sie möglicherweise fest, dass dies nicht kompiliert werden kann.

Mark Byers
quelle
10
Können Sie bitte den Unterschied zwischen "t.CustID == custIdToQuery" und "t.CustID.Equals (custIdToQuery)" erklären? Vielen Dank im Voraus
Neel
2
@Neel Schauen Sie sich diese Frage an, um den Unterschied zwischen ==und zu erklären.Equals() : stackoverflow.com/questions/814878/…
Alex
Die Lösungslogik von 2011 hat 2018 funktioniert! Super würdig!
Yeshwant Mudholkar
29

Ich hatte das gleiche Problem mit einem nullable int. Die Verwendung von == funktioniert stattdessen gut, aber wenn Sie .Equals verwenden möchten, können Sie es mit dem Wert der nullbaren Variablen vergleichen

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

Ich hatte das gleiche Problem, als ich versuchte. Gleichungen mit einer nullbaren Dezimalstelle. Die Verwendung von == funktioniert stattdessen gut. Ich denke, das liegt daran, dass nicht versucht wird, den genauen "Typ" der Dezimalstelle zu finden. zu dezimal.

Dave Stuart
quelle
4
Beachten Sie, dass dies im Kontext von a steht IQueryable, sodass es nicht in regulären C # -Code kompiliert wird. Es wird zu einem Ausdruck, der an einen Abfrageanbieter übergeben wird. Diese Abfrage - Provider können tun , was mit der Abfrage will, und es kann behandeln Equalsund ==die gleiche oder nicht.
Servy
Früher habe ich .Equal()zu vergleichen Int32?mit Int32. Da Int32?enthalten sollte Int32und null, dachte ich , es würde funktionieren. Aber es war nicht so. ==hat funktioniert.
Matrix
1

Ich hatte das gleiche Problem und verglich das Sammlungsobjekt "User"mit dem ganzzahligen Datentyp "userid"( x.User.Equals(userid))

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

und richtige Abfrage ist x.UserId.Equals(userid)

from user in myshop.UserPermissions.Where(x => x.IsDeleted == false && x.UserId.Equals(userid))
Satish Kumar Sonker
quelle
Dies ist ein anderes Problem, Sie vergleichen Äpfel und Orangen.
Lasse V. Karlsen
wie es anders ist. während ich das gleiche Problem konfrontiert habe. Ich poste diese Antwort nur als Referenz nur für andere.
Satish Kumar Sonker
0

In meinem Fall habe ich den direkten Aufruf von (sender as Button).Textin einen indirekten Aufruf mit einer temporären Variable geändert , hat funktioniert. Arbeitscode:

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);
    }

Buggy-Code:

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
quelle