2012-08-26 59 views
5

我是新來的LINQ。我需要運行聯接​​兩列(AnonymousUser.AnonymousIduniqueidentifier和comment.UserId是nvarchar(100))查詢,類似如下:linq加入GUID和字符串列

 using (CommentEntities db = new CommentEntities()) 
     { 
      // filteredComments is a query that is not run until the next .ToList() 
      IQueryable<Comment> filteredComments = this.CommentGetList(...); 
      var query = from comment in filteredComments 
         // following line is the syntax error, because columns' types don't match 
         join user in db.AnonymousUsers on comment.UserId equals user.AnonymousId into gj 
         from userNull in gj.DefaultIfEmpty() 
         select new CommentWithName 
         { 
          Comment = comment, 
          UserId = comment.UserId, 
          FirstName = (userNull == null ? "" : userNull.Name), 
          LastName = "", 
          Email = (userNull == null ? "" : userNull.Email) 
         }; 
      return query.ToList(); 
     } 

首先,我很高興與.ToString()編寫查詢!事實證明,實體框架不知道如何將其轉換爲SQL。 Guid.Parse(string)也是如此。另外new Guid(string)不能在linq中用於實體(只允許無參數的構造函數)!

所以在搜索後,我發現在EF 4.0中做這種事情是不可能的!我將我的代碼遷移到一個存儲過程,我對此並不滿意。

是否有可能告訴實體框架在SQL中使用CAST

有沒有解決這個問題的方法?有什麼方法可以讓代碼中的邏輯?

注意:我打算在之一做一個GO。否則,一種可能的解決方案是從第一個表獲取實體,並將這些Id放入列表中,並從第二個表中獲取實體。

+0

如果'comment.UserId'是一個GUID的字符串表示,那麼是否更容易將該列轉換爲唯一標識符?這可能是一個更好的解決方案,而不是讓實體框架在SQL中爲您執行此操作。 – mclark1129

+0

不幸的是,它並不總是GUID。它可能是基於用戶類型的'Guid'或'int'。 – Ashkan

+0

您是否嘗試使用['Guid.Parse(string)'](http://stackoverflow.com/a/8067647/484214)而不是'new Guid(string)'? –

回答

0

在應用這些方法之前調用toList()。像:

var Product = db.Products.Where(p => p.ProductId == Guid.Parse("B4E913F9-166C-49BA-AADE-6DB889D1756F")).Single(); 

會拋出一個

C#LINQ到實體無法識別方法「的System.Guid解析」(System.String)」的方法,而這種方法不能被翻譯成店表達

但這個工程:

var Product = db.Products.ToList().Where(p => p.ProductId == Guid.Parse("B4E913F9-166C-49BA-AADE-6DB889D1756F")).Single() 

PS:我想你將失去懶惰加載,但你可以在調用.ToList()之前用.Include進行預先加載。

+0

如果它適用於沒有關係的兩個表,那麼使用預先加載是一個好主意。 P.S:表格之間沒有關係評論和匿名用戶 – Ashkan

+2

您將最終使用此選項將整個列表拖入內存。只有當產品表很小時才這樣做。 –

+0

沒有評論的表是一個非常大的表... – Ashkan

0

如果您list是對象列表,你可以將其轉換爲已GUID作爲標識符的類型,首先要創建新的匿名類型,然後將其過濾的基礎上UserId,確保UserId這是int型的,不會包括在加盟:

 int output = 0; 

    var secondList = list.Where(x=>!int.TryParse(x.UserID, out output)) 
        .Select(x=>new {Comment = x, ID = new Guid(x.UserID)) 
        .ToList(); 

現在,您可以使用secondList在db上運行您的查詢。

+0

我沒有提到'list'的類型是'IQueryable '。 – Ashkan

+1

所以你的意思是它是一個數據庫項目,在這種情況下,我會提供使用存儲過程。 –

+0

+1。那麼你同意EF沒有辦法做到這一點? 更新版本的EF如何? – Ashkan