2013-08-02 80 views
8

我對linq和實體框架非常新穎。我正試圖解決一個問題,爲什麼下面的不工作。產生的錯誤是「無法創建類型爲」匿名類型「的常量值,在此上下文中僅支持基本類型或枚舉類型。」無法創建「匿名類型」類型的常量值。在這種情況下只支持基本類型或枚舉類型

我試過這麼多不同的方法,但仍然得到一個與原始類型有關的錯誤。如果有人可以看看下面的代碼,並希望指出哪裏出了問題,我將不勝感激。

 public Entities.BikeData[] GetBikesWithExpiredSyncDeadline(int noOfDays) { 

     using (OfficeEntities cxt = GetContext()) 
     using (ReportingEntities RepCxt = GetReportingContext()) { 
      Data.Repository.Abstract.IBikeRepository BikeRepos = new Data.Repository.Concrete.BikeRepository();     

      var details = (from sd in cxt.BikeDetails 
             where sd.autoreminder == true 
              && (sd.lastremindersent == null || sd.lastremindersent < EntityFunctions.AddDays(DateTime.UtcNow, noOfDays * -1)) 
              && (sd.emailaddress != null && sd.emailaddress.Trim() != "") 
             select new { 
              Serial = sd.Serial, 
              EmailAddress = sd.emailaddress 
             }).ToList(); 

      var resLst = (from r in RepCxt.RegisteredBikes 
          join d in details on r.Serial equals d.Serial 
          join cs in cxt.CompanySettings.ToList() on r.CompanyID equals cs.CompanyID 
          where (!r.lastupdate.HasValue || r.lastupdate < EntityFunctions.AddDays(DateTime.UtcNow, cs.AutoNotificationFrequency * -1)) 
          select new Entities.BikeData { 
           ID = r.ID, 
           Name = r.Ship, 
           Serial = r.Serial, 
           LastUpdate = r.lastupdate, 
           DaysSinceLastSync = (r.lastupdate.HasValue? EntityFunctions.DiffDays(r.lastupdate.Value, DateTime.UtcNow).Value : -1), 
           EmailAddress = (d.EmailAddress == null ? string.Empty : (String.IsNullOrEmpty(d.EmailAddress) ? r.ShipEmailAddress : d.EmailAddress)) 
          }); 

      return resLst.ToArray(); 
     } 
    } 

UPDATE

我已經採取了與此不同的方法現在創建一個視圖,所以我不再需要做跨語境EF連接。我希望你能幫助下面的人。

當我運行objectQuery.ToTraceString()時,它向我提供了有效的SQL,它返回數據庫中的記錄,但EntityFramework中的resLst始終返回0.是否有任何顯而易見的事情發生?

var resLst = (from ls in cxt.BikeLastUpdates 
          where (!ls.lastupdate.HasValue || ls.lastupdate < EntityFunctions.AddDays(DateTime.UtcNow, ls.AutoNotificationFrequency * -1)) 
          && (ls.autoreminder ==true) 
          && (ls.lastremindersent == null || ls.lastremindersent < EntityFunctions.AddDays(DateTime.UtcNow, 3 * -1)) 
          && (ls.emailaddress !=null && ls.emailaddress.Trim() != "") 
          select new Entities.BikeData{ 
           ID = (ls.ID ?? new Guid()), 
           Name = ls.Bike, 
           Serial = ls.Serial, 
           LastUpdate = ls.lastupdate, 
           EmailAddress = (String.IsNullOrEmpty(ls.emailaddress) ? ls.ShipEmailAddress : ls.emailaddress) 
          }); 

      var objectQuery = resLst as ObjectQuery; 

      return resLst.ToArray(); 
+0

爲了您的更新,我會建議使用[Sql Server Profiler](httt p://msdn.microsoft.com/en-us/library/ms181091.aspx)並捕獲EF實際發送到服務器的SQL。 –

+0

乾杯隊友。愚蠢的連接字符串問題。你生活和學習:-) – JIbber4568

回答

5

問題是ToList()調用的詳細信息。在EF中,如果IEnumerable是簡單類型(例如int),則只能引用Query中的IEnumerable。但是,您可以參考另一個IQueryable。因此,放棄ToList()調用應該使這個工作。

編輯:同樣,你應該放棄對ctx.CompanySettings的ToList()調用。

如果你把細節的ToList()這將只執行1查詢,而不是2的附加優勢,英孚將產生類似:

SELECT ... 
FROM RegisteredBikes rb 
JOIN (
    /* this is your "details" IQueryable */ 
    SELECT Serial, EmailAddress 
    FROM BikeDetails 
    WHERE ... 
) bd 
    ON rb.Serial = b.Serial 
JOIN CompanySettings cs 
    ON ... 
WHERE ... 

編輯:整個環境要做到這一點,你需要把查詢放入內存中(例如調用AsEnumerable()並在那裏進行相關連接)如果連接起到了過濾器的作用,並且在SQL中發生這些事情很重要,可以考慮使用Contains(),例如

var serials = details.Select(d => d.Serial); 
var filtered = RepCtxt.RegisteredBikes.Where(r => details.Contains(r.Serial); 
+0

謝謝你。這樣做的原因是我們不得不加入交叉上下文。據我所知沒有.ToList()我們無法查詢交叉上下文。有沒有不同的方法,我應該採取以允許跨上下文加入? – JIbber4568

+0

@ JIbber4568爲了加入跨上下文,您需要將整個公司設置表拉入內存並使用WHERE IN()(包含在EF中)進行過濾。 – ChaseMedallion

+0

感謝您的幫助。我已經採取了與此稍有不同的方法,但現在遇到了實體框架繼承數據庫結果的問題。上述更新中是否有明顯的可能導致這種情況?謝謝 – JIbber4568

相關問題