2016-11-22 167 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; 
} 

它看起来有些神奇。我使用字典而不是对象。它可以以更清晰的方式制作(提取几种方法),但这个想法应该清楚。

然后,在序列化过程中,将根据您的需要进行呈现。