Linq Query tiếp tục thông báo “Không thể tạo một giá trị không đổi của kiểu System.Object…”, tại sao?


94

Sau đây là mẫu mã:

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

tôi không thể hiểu tôi đang làm gì sai. Tôi tiếp tục nhận được "Không thể tạo giá trị không đổi của loại 'System.Object'. Chỉ các loại nguyên thủy ('chẳng hạn như Int32, String và Guid') được hỗ trợ trong ngữ cảnh này."

Câu trả lời:


232

Sử dụng == thay vì bằng:

where t.CustID == custIdToQuery

Nếu các loại không chính xác, bạn có thể thấy rằng điều này không được biên dịch.


10
Bạn có thể vui lòng giải thích sự khác biệt giữa "t.CustID == custIdToQuery" và "t.CustID.Equals (custIdToQuery)". cảm ơn trước
Neel

2
@Neel Hãy xem câu hỏi này để biết lời giải thích về sự khác biệt giữa ==.Equals(): stackoverflow.com/questions/814878/…
Alex

Giải pháp logic 2011 hoạt động cho năm 2018! Tuyệt vời đáng giá!
Yeshwant Mudholkar

29

Tôi đã gặp vấn đề tương tự với một int nullable. Thay vào đó, sử dụng == hoạt động tốt, nhưng nếu bạn muốn sử dụng .Equals, bạn có thể so sánh nó với giá trị của biến nullable, vì vậy

where t.CustID.Value.Equals(custIdToQuery)

9

Tôi đã gặp vấn đề tương tự khi cố gắng thực hiện .Equals với số thập phân có thể giải được. Sử dụng == thay thế hoạt động tốt. Tôi đoán điều này là do nó không cố gắng khớp chính xác "loại" của số thập phân? sang số thập phân.


4
Hãy nhớ rằng điều này nằm trong ngữ cảnh của an IQueryable, vì vậy nó không được biên dịch thành mã C # thông thường. Nó trở thành một biểu thức được chuyển đến một trình cung cấp truy vấn. Nhà cung cấp truy vấn đó có thể làm bất cứ điều gì muốn với truy vấn và nó có thể xử lý Equals==tương tự hoặc không.
Servy

Tôi đã sử dụng .Equal() so sánh Int32?với Int32. Vì Int32?được cho là chứa Int32null, tôi nghĩ nó sẽ hoạt động. Nhưng nó đã không. ==đã làm việc.
ma trận

1

Tôi đã gặp phải vấn đề tương tự và tôi đang so sánh Đối tượng Bộ sưu tập "User"với kiểu dữ liệu số nguyên "userid"( x.User.Equals(userid))

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

và Truy vấn đúng là x.UserId.Equals(userid)

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

Đây là một vấn đề khác, bạn đang so sánh táo và cam.
Lasse V. Karlsen

nó khác nhau như thế nào. trong khi tôi đã phải đối mặt với cùng một vấn đề. Tôi chỉ đăng câu trả lời này chỉ để tham khảo cho những người khác.
Satish Kumar sonker

0

Trong trường hợp của tôi, tôi đã thay đổi cuộc gọi trực tiếp của (sender as Button).Text gián tiếp bằng cách sử dụng một temp var, đã hoạt động. mã làm việc:

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

mã lỗi:

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);
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.