2016-11-22 272 views
1

我的代碼工作,這將給兩個匿名類型的笛卡爾乘積的笛卡爾乘積。這2個匿名類型是從數據庫生成的。匿名類型

代碼1匿名類型:

private IEnumerable<object> GetItem() 
    { 
     return _unitOfWork.GetRepository<Item>() 
      .ListAll() 
      .Select(x => new 
      { 
       itemId = x.Id, 
       itemName = x.Name 
      }) 
    } 

守則第2匿名類型:

private IEnumerable<object> GetVenue() 
    { 
     return _unitOfWork.GetRepository<Venue>() 
      .ListAll() 
      .Select(x => new 
      { 
       locationName = x.Address.City, 
       venueId = x.VenueId, 
       venueName = x.Name 
      }) 
    } 

我有如下方法獲取數據並進行笛卡爾乘積並返回數據。

public object GetRestrictLookupInfo(IEnumerable<int> lookupCombinations) 
    { 
     IEnumerable<object> restrictList = new List<object>(); 
     if (lookupCombinations.Contains(1)) 
     { 
      var tempProductProfileList = GetItem(); 
      restrictList = tempProductProfileList.AsEnumerable(); 
     } 
     if (lookupCombinations.Contains(2)) 
     { 
      var tempProductGroupList = GetVenue(); 
      restrictList = (from a in restrictList.AsEnumerable() 
          from b in tempProductGroupList.AsEnumerable() 
          select new { a, b }); 
     } 
     return restrictList; 
    } 

我有控制器調用此方法並返回json格式的數據。預計

控制器代碼

public HttpResponseMessage GetData(IEnumerable<int> lookupCombinations) 
    { 
     var lookupRestrictInfo = _sellerService.GetRestrictLookupInfo(lookupCombinations); 
     return Request.CreateResponse(HttpStatusCode.OK, lookupRestrictInfo); 
    } 

迴應是: - 我收到

[ { 
    "itemId": 1, 
    "itemName": "Music",   
    "locationName": "Paris", 
    "venueId": 99, 
    "venueName": "Royal Festival Hall" 
} ] 

響應是

[ { 
"a": { 
    "itemId": 1, 
    "itemName": "Music"   
}, 
"b": { 
    "locationName": "Paris", 
    "venueId": 99, 
    "venueName": "Royal Festival Hall" } }] 

我無法獲得預期的JSON字符串,請幫助實現它。

+1

不知道如何使用反射來遍歷每個匿名類型的成員或通過指定'a'和'b'的成員顯式構造一個新的匿名類型。 –

+1

你真的需要'GetItem'和'GetVenue'方法嗎? – MaKCbIMKo

回答

1

爲了在輸出端產生一個單一的項目,你需要創建一個新的類型,命名或匿名。由於您使用object真是讓人不是實際的類型,最快捷的方法是將它們轉換成dynamic

var tempProductGroupList = GetVenue(); 
restrictList = (from a in restrictList.Cast<dynamic>() 
       from b in tempProductGroupList.Cast<dynamic>() 
       select new { 
        itemId = (int)a.itemId, 
        itemName = (string)a.itemName,   
        locationName = (string)b.locationName, 
        venueId = (int)b.venueId, 
        venueName = (string)b.venueName 
       }); 

此代碼是緊耦合產生兩個列表的代碼,因爲它假定的字段名的知識類型動態傳遞給它。源代碼數據結構的任何變化都必須跟隨代碼組合的變化。另外,它會影響運行時檢查,所以你需要非常小心這個代碼。

0

嘗試創建一個簡單的對象,而不是嵌套:

select new { a.itemId, a.itemName, b.locationName }

+1

因爲'a'和'b'是物體,所以不可能做到這一點。 – MaKCbIMKo

0

你應該儘可能簡單的代碼,顯示你的問題開始;上面的代碼有很多的複雜性,可能(也可能不會)有什麼與你的問題。這是關於操縱匿名類型嗎?用LINQ做笛卡爾產品?將object轉換爲JSON?

這裏是一個可能的答案是什麼,你可能會尋找;請注意,您可以使用泛型代替object繞過匿名類型。

namespace AnonymousTypes 
{ 
    class Program 
    { 
     static string Serialize(object o) 
     { 
      var d = (dynamic)o; 
      return d.ItemId.ToString() + d.ItemName + d.VenueId.ToString() + d.LocationName + d.VenueName; 
     } 
     static string GetData<T>(IEnumerable<T> result) 
     { 
      var retval = new StringBuilder(); 
      foreach (var r in result) 
       retval.Append(Serialize(r)); 
      return retval.ToString(); 
     } 
     static string GetRestrictLookupInfo() 
     { 
      var restrictList = new[] { new { Id = 1, Name = "Music" }, new { Id = 2, Name = "TV" } }; 
      var tempProductGroupList = new[] { new { LocationName = "Paris", Id = 99, Name = "Royal Festival Hall" } }; 
      var result = from item in restrictList 
         from venue in tempProductGroupList 
         select new 
         { 
          ItemId = item.Id, 
          ItemName = item.Name, 
          LocationName = venue.LocationName, 
          VenueId = venue.Id, 
          VenueName = venue.Name 
         }; 
      return GetData(result); 
     } 

     public static string GetData() 
     { 
      return GetRestrictLookupInfo(); 
     } 

     static void Main(string[] args) 
     { 
      var result = GetData(); 
     } 
    } 
} 

如果這不是你要找的,你可能會與代碼不使用匿名類型開始的東西,如

namespace AnonymousTypes 
{ 
    sealed class Item 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
    } 

    sealed class Venue 
    { 
     public string LocationName { get; set; } 
     public int Id { get; set; } 
     public string Name { get; set; } 
    } 

    sealed class ItemAndVenue 
    { 
     public int ItemId { get; set; } 
     public string ItemName { get; set; } 
     public string LocationName { get; set; } 
     public int VenueId { get; set; } 
     public string VenueName { get; set; } 
    } 

    class Program 
    { 
     static IEnumerable<Item> GetItem() 
     { 
      return new[] { new Item { Id = 1, Name = "Music" } }; 
     } 

     static IEnumerable<Venue> GetVenue() 
     { 
      return new[] { new Venue { LocationName = "Paris", Id = 99, Name = "Royal Festival Hall" } }; 
     } 

     static IEnumerable<ItemAndVenue> GetRestrictLookupInfo() 
     { 
      var restrictList = GetItem(); 
      var tempProductGroupList = GetVenue(); 
      var result = from item in restrictList 
        from venue in tempProductGroupList 
        select new ItemAndVenue 
        { 
         ItemId = item.Id, 
         ItemName = item.Name, 
         LocationName = venue.LocationName, 
         VenueId = venue.Id, 
         VenueName = venue.Name 
        }; 
      return result; 
     } 

     static string GetData() 
     { 
      var v = GetRestrictLookupInfo().First(); 
      return v.ItemId.ToString() + v.ItemName + v.VenueId.ToString() + v.LocationName + v.VenueName; 
     } 

     static void Main(string[] args) 
     { 
      var result = GetData(); 
     } 
    } 
} 
+1

你不應該發佈回答要求澄清問題,或指出問題的問題。答案是你在問題中發佈*答案*的地方。您應該使用評論來澄清問題或指出問題的問題,如果您不清楚問題實際上在問什麼,應該投票結束問題。 – Servy

+0

@Servy大量的代碼不會很好地作爲評論。 –

+0

但這不是問題的答案,所以它不屬於答案。 – Servy

0

就像一個選項:

public object GetRestrictLookupInfo(IEnumerable<int> lookupCombinations) 
{ 
    List<Dictionary<string, object>> result = new List<Dictionary<string, object>>(); 
    if (lookupCombinations.Contains(1)) 
    { 
     var tmp = _unitOfWork.GetRepository<Item>() 
          .ListAll() 
          .Select(x => new 
          { 
           itemId = x.Id, 
           itemName = x.Name 
          }) 
          .Select(x => 
          { 
           var dic = new Dictionary<string, object>(); 

           dic.Add(nameof(x.itemId), x.itemId); 
           dic.Add(nameof(x.itemName), x.itemName); 

           return dic; 
          }); 

     result.AddRange(tmp); 
    } 
    if (lookupCombinations.Contains(2)) 
    { 
     var tmp = _unitOfWork.GetRepository<Venue>() 
          .ListAll() 
          .Select(x => new 
          { 
           locationName = x.Address.City, 
           venueId = x.VenueId, 
           venueName = x.Name 
          }) 
          .Select(x => 
          { 
           var dic = new Dictionary<string, object>(); 

           dic.Add(nameof(x.locationName), x.locationName); 
           dic.Add(nameof(x.venueId), x.venueId); 
           dic.Add(nameof(x.venueName), x.venueName); 

           return dic; 
          }); 

     result = result.SelectMany(r => tmp.Select(t => r.Concat(t))); 
    } 

    return result; 
} 

它看起來有些神奇。我使用字典而不是對象。它可以以更清晰的方式製作(提取幾種方法),但這個想法應該清楚。

然後,在序列化過程中,將根據您的需要進行呈現。