2014-02-12 52 views
1

我使用EF和MVC來訪問SQL數據庫中的數據,並且希望控制器使用json進行通信Android所以不使用視圖)。「無法創建一個類型爲'匿名類型'的空常量值」爲空的列db「

我發現有必要改變控制器以通過匿名對象來投影數據,以避免主表和參考表之間的循環引用問題,但是現在當嘗試爲集合創建json時會導致一個新問題當基礎記錄在可選外鍵字段中包含空值時。

表用戶具有(爲了示例)代碼/描述表的兩個外鍵語言和國家,語言是強制性的,國家是可選的。

我發現我可以通過測試空ID成功更換空國元中,JSON出來罰款...

{ 
"UserID": 3, 
"UpdatedWhen": null, 
"Country": null, 
"Language": { 
    "LanguageID": 1, 
    "LocalName": "English" 
    } 
} 

...但現在已經發現,這並不當我有多個用戶對象來處理時工作。

public JsonResult Index() 
    { 
     var users = from user in db.Users 
        select new 
        { user.UserID, 
         <snip> 
         user.CreatedWhen, 
         user.UpdatedBy, 
         user.UpdatedWhen, 
         Country = (user.Country == null ? null : new { user.Country.CountryID, user.Country.LocalName }), 
         Language = new { user.Language.LanguageID, user.Language.LocalName } }; 

     return Json(users.ToList(), JsonRequestBehavior.AllowGet); 
    } 

從我讀過的問題是我的.ToList(),它並不像空Country對象,因爲如果我處理只是一個單一的用戶例如

private object projectUser(User user) 
    { 
     return new 
     { 
      user.UserID, 
      <snip> 
      user.UpdatedWhen, 
      Country = (user.Country == null ? null : new { user.Country.CountryID, user.Country.LocalName }), 
      Language = new { user.Language.LanguageID, user.Language.LocalName } }; 

...它工作得很好。

我已經找到了,但根本找不到類似的如何更好地做到這一點的例子,任何人都可以請建議一種方式。

在此先感謝。

回答

1

你是不是能夠創造出null恆定值,在linq to entity查詢,這是當您要執行什麼這行users.ToList()告訴你....

而且這種方法private object projectUser(User user)的工作,因爲user一直在內存中取出已經....

解決你的問題,你可以獲取數據,然後,在內存選擇上的數據,這樣的:

var users = (from user in db.Users 
      join country in db.Countries on user.CountryID equals country.ID into joinedList 
      from country in joinedList.DefaultIfEmpty() 
      select new {user, country}) 
      .ToList() // your data fetched to memory by this line 
      .Select(u => new 
      { 
       u.user.UserID, 
       u.user.CreatedWhen, 
       u.user.UpdatedBy, 
       u.user.UpdatedWhen, 
       Country = (u.country == null ? null : new { u.country.CountryID, u.country.LocalName }), 
       Language = new { u.user.Language.LanguageID, u.user.Language.LocalName } } 
      }) 
      .ToList(); 

作爲替代,可以設置國家(anonymouse type)的屬性爲默認,而不是null值,如:

var users = (from user in db.Users 
      join country in db.Countries on user.CountryID equals country.ID into joinedList 
      from country in joinedList.DefaultIfEmpty() 
      select new { 
       user.UserID, 
       user.CreatedWhen, 
       user.UpdatedBy, 
       user.UpdatedWhen, 
       Language = new { user.Language.LanguageID, user.Language.LocalName }, 
       Country = new { 
        CountryID = country == null ? default(Guid) : country.CountryID, // i assume type of CountryID is Guid 
        LocalName = country == null ? "" : country.LocalName 
        } 
       }) 
       .ToList(); 
+0

一個有趣的方法,謝謝你。它(第一個)目前並沒有給出我期望的結果 - 所有的國家都是空白的 - 但我可以看到你要去的地方。我會有一點戲劇,應該能夠調整它的工作。再次感謝。 – Mike

+0

你的數據是否有效?與這兩個查詢你會得到相同的結果?如果是的話,我認爲你的數據有問題,或者在連接條件下,需要檢查'user.CountryID等於國家'這部分的查詢。ID' –

+0

數據是好的,我會在週末的晚些時候回到代碼的這一部分,我只是在讓Android應用程序與Web服務交談的中間,稍微複雜的是Eclipse/Android在Linux上運行,而Web服務在W7 VMware客戶機上運行,​​調試稍微麻煩。很快回來(ish)... – Mike

0

突破查詢和看到最新結果中的每個步驟,找出問題是從您的數據與否:

var UsersQuery = (from user in db.Users 
        join country in db.Countries on user.CountryID equals country.ID into joinedList 
        from country in joinedList.DefaultIfEmpty() 
        select new {user, country}) 
        .ToList(); // your data fetched to memory by this line 

var Users = UsersQuery.Select(u => new 
     { 
      u.user.UserID, 
      u.user.CreatedWhen, 
      u.user.UpdatedBy, 
      u.user.UpdatedWhen, 
      Country = (u.country == null ? null : new { u.country.CountryID, u.country.LocalName }), 
      Language = new { u.user.Language.LanguageID, u.user.Language.LocalName } } 
     }) 
     .ToList(); 
+0

檢查確認這部分查詢是否正常,'user.CountryID等於country.ID' –

相關問題