2013-05-14 43 views
5

Tôi đã ghi một truy vấn LINQ để điền vào một listview nhưng nó sử dụng phương thức .ToString() mà rõ ràng là không được phép. Khi tôi sử dụng đoạn mã sau tôi nhận được thông báo lỗi:Sử dụng ToString() trong truy vấn LINQ?

Error: LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression

Có cách nào để sử dụng ToString() trong LINQ hoặc nếu đó là không thể là giải pháp cho chuyển đổi một DateTime để String trong truy vấn là gì . Hãy hôn mà ReleaseDateName là một chuỗi và ngày phát hành là một DateTime

using (var db = new ReleaseInfo()) 
{ 
    lvReleaseInfo.DataSource = (from r in db.MediaReleases 
           join rn in db.ReleaseNames 
           on new { MediaReleaseID = r.MediaReleaseID, CultureCodeID } equals new { rn.MediaReleaseID, rn.CultureCodeID } 
           join plat in db.MediaPlatforms 
           on new { MediaPlatformID = r.MediaPlatformID, CultureCodeID } equals new { plat.MediaPlatformID, plat.CultureCodeID } 
           join pub in db.MediaPublishers 
           on new { MediaPublisherID = r.MediaPublisherID, CultureCodeID } equals new { pub.MediaPublisherID, pub.CultureCodeID } 
           join c in db.Countries 
           on new { CountryID = r.CountryID, CultureCodeID } equals new { c.CountryID, c.CultureCodeID } 
           join rd in db.ReleaseDates 
           on new { MediaReleaseID = r.MediaReleaseID, CultureCodeID } equals new { rd.MediaReleaseID, rd.CultureCodeID } 
           join a in db.AffiliateLinks 
           on new { MediaReleaseID = r.MediaReleaseID, CultureCodeID } equals new { a.MediaReleaseID, a.CultureCodeID } 
           where r.SectionID == SectionID 
           select new 
           { 
            rn.ReleaseTitle, 
            plat.MediaPlatformName, 
            pub.MediaPublisherName, 
            c.CountryName, 
            ReleaseDate = (rd.ReleaseDate == null ? rd.ReleaseDateName : rd.ReleaseDate.ToString()), 
            a.AffiliateLinkAddress 
           }).ToList(); 
    lvReleaseInfo.DataBind(); 
} 

Trả lời

7

Vì bạn đang thể hóa truy vấn của bạn vào danh sách dù sao, bạn có thể thực hiện chuyển đổi ở phía bên NET, chứ không phải là trong RDBMS, như thế này:

... 
select new { 
    rn.ReleaseTitle, 
    plat.MediaPlatformName, 
    pub.MediaPublisherName, 
    c.CountryName, 
    rd.ReleaseDateName, 
    rd.ReleaseDate, 
    a.AffiliateLinkAddress 
}).AsEnumerable() // <<== This forces the following Select to operate in memory 
.Select(t => new { 
    t.ReleaseTitle, 
    t.MediaPlatformName, 
    t.MediaPublisherName, 
    t.CountryName, 
    ReleaseDate = t.ReleaseDateName ?? t.ReleaseDate.ToString() 
    t.AffiliateLinkAddress   
}).ToList(); 

Kể từ khi ToString() được gọi trên một phần tử từ IEnumerable<T>, nó sẽ không còn thất bại. Cũng lưu ý việc sử dụng toán tử ?? thay cho điều kiện không kiểm tra ? : có điều kiện.

+0

Tôi mới sử dụng LINQ to Etityes, bạn có thể giải thích cách phần .Select hoạt động không? –

+2

@MatthewVerstraete '.Select' chỉ là cú pháp phương thức. Nó giống như khi bạn sử dụng 'select' trong cú pháp truy vấn. 't => {...}' là một biểu thức lambda. Về cơ bản nó nói về mỗi phần tử chúng ta chọn làm bất cứ điều gì ở bên phải của toán tử '=>'. – evanmcdonnal

+0

Cảm ơn, tôi cũng đã suy nghĩ về việc chỉ chuyển đổi này thành một Proc trên máy chủ SQL vì nó là một tham gia khá phức tạp. Chuyển đổi sang một Proc cũng sẽ cho phép tôi thực hiện logic trên phía máy chủ của SQL. Sẽ có một nâng cấp hiệu suất khá để đi proc vs phương pháp của bạn? –

0

Vấn đề là bạn không thể gọi ToString() trên một trường cho đến khi nó được deserialized. Vì vậy, thay vì cố gắng gọi ToString() trong truy vấn, chỉ cần làm điều đó trên kết quả sau đó.

Trong cơ sở dữ liệu giá trị bạn đang hoạt động không có khái niệm về ToString(), đó là lý do bạn gặp lỗi. Truy vấn có thể nhìn và cảm thấy giống như mã C# nhưng hãy nhớ rằng dưới các bìa được chuyển thành truy vấn SQL giống như bất kỳ truy vấn nào khác. Sau khi bạn lấy lại danh sách, bạn có thể viết một truy vấn LINQ rất đơn giản để giải quyết vấn đề.

Các vấn đề liên quan