ASP.NET LINQ查询用于过滤和循环遍历多个表

时间:2017-11-04 08:37:06

标签: c# asp.net json entity-framework linq

我为“App”和“AgeGroup”提供了两个独立的域模型类。 App Class包含几个基本的整数和字符串属性,AgeGroup类也是如此。

我想要实现的是AppOrder所有应用程序的JSON输出及其属性,嵌套在由其GroupOrder属性排序的关联AgeGroup中

必需的示例JSON输出结构

"Looped List of Age Groups, order by GroupOrder"
      "Looped List of Apps, order by App Order"

 First Age Group
    Foo App Name
        Foo App Icon
        Foo App Store URL
    Bar App Name
        Bar App Icon
        Bar App Store URL
 Second Age Group
    Tur App Name
        Tur App Icon
        Tur App Store URL
    Puk App Name
        Puk App Icon
        Puk App Store URL
  and so on...

到目前为止我的方法:

以下是我在“App.cs”

中的内容
public int Id { get; set; }
public string Name { get; set; }
public string StoreURL { get; set; }
public int AppOrder { get; set; }
public string AppIcon { get; set; }

public AgeGroup AgeGroup { get; set; }    // Linked to AgeGroup Class
public int AgeGroupId { get; set; }

“AgeGroup.cs”类中,我有以下

public int Id { get; set; }
public int GroupOrder { get; set; }
public string Name { get; set; }

并在 AppsController.cs

    [HttpGet]
    [Route("api/groups")]

    public IHttpActionResult AppsByGroup ()
    {
        var apps = _context.Apps
            .OrderBy(a => a.AppOrder)
            .Select(a => new
            {
                a.Name,
                a.StoreURL,
                a.AppIcon,
                AgeGroup = a.AgeGroup.Name
            }).GroupBy(a => a.AgeGroup);

       return Json(apps);
    }

它为我提供了正确的输出但没有AgeGroup Names。

[
  [ // Here I wanted the AgeGroup Name from the AgeGroup Table (Group A)
    {
        "Name": "First App for Group A",
        "StoreURL": "some string",
        "AppIcon": "icon string",
        "AgeGroup": "Group A"
    },
    {
        "Name": "2nd App Group A",
        "StoreURL": "aslfdj",
        "AppIcon": "asljf",
        "AgeGroup": "Group A"
    },
    {
        "Name": "3rd App Group A",
        "StoreURL": "aslfdj",
        "AppIcon": "alsfdj",
        "AgeGroup": "Group A"
    }
  ],
  [ // Here I wanted the AgeGroup Name from the AgeGroup Table (Group B)
    {
        "Name": "1st App GroupB",
        "StoreURL": "alsfdj",
        "AppIcon": "alsdjf",
        "AgeGroup": "Group B"
    },

//and so on...

5 个答案:

答案 0 :(得分:3)

试试这个

public IHttpActionResult AppsByGroup() {

   var apps = _context.Apps.OrderBy(a => a.AppOrder);
   var groups = _context.AgeGroups.OrderBy(g => g.GroupOrder);

   var result = groups.Select(x => new {
         AgeGroupName = x.Name,
         Apps = apps
           .Where(y => x.Id == y.AgeGroupId)
           .Select(y => new {
              AppName = y.Name,
              AppIcon = y.AppIcon,
              StoreURL = y.StoreURL
            })
         });

   return Json(result);
}

它提供以下输出

[
{
    "AgeGroupName": "Group C",
    "Apps": [
        {
            "AppName": "C Group App",
            "AppIcon": "Some string",
            "StoreURL": "64"
        }
    ]
},
{
    "AgeGroupName": "Group A",
    "Apps": [
        {
            "AppName": "App 2nd for Group AA",
            "AppIcon": "Some string",
            "StoreURL": "654"
        },
        {
            "AppName": "App 1 for Group A",
            "AppIcon": "Some string",
            "StoreURL": "654"
        }
    ]
},
{
    "AgeGroupName": "Group B",
    "Apps": [
        {
            "AppName": "App 1 for Group B",
            "AppIcon": "Some string",
            "StoreURL": "31"
        }
    ]
}
]

希望这会对你有所帮助。

答案 1 :(得分:2)

我建议让代码更容易理解和调试,从视图模型开始表示要返回的数据

public class AgeGroupVM
{
    public string Name { get; set; }
    public IEnumerable<AppVM> Apps { get; set; }
}
public class AppVM
{
    public string Name { get; set; }
    public string StoreURL { get; set; }
    public string AppIcon { get; set; }
}

然后您需要订购数据并按Name

AgeGroup属性对其进行分组
var data = _context.Apps
    .OrderBy(x => x.AgeGroup.GroupOrder) // order by AgeGroup first
    .ThenBy(x => x.AppOrder) // then by the AppOrder
    .GroupBy(x => x.AgeGroup.Name) // group by the AgeGroup
    .Select(x => new AgeGroupVM // project into the view model
    {
        Name = x.Key,
        Apps = x.Select(y => new AppVM
        {
            Name = y.Name,
            StoreURL = y.StoreURL,
            AppIcon = y.AppIcon
        })
    });
return Json(data);

答案 2 :(得分:1)

看起来你有一对多的关系(每个AgeGroup包含许多应用,但每个App只能有一个AgeGroup)。因此,您可以将AgeGroup类更改为以下内容:

class AgeGroup {
 public ICollection<Apps> Apps { get; set; }
 // your other properties here

  public AgeGroup() {
   Apps = new Collection<Apps>();
 }
}

将AgeGroup添加到DbContext(如果之前没有这样做),然后在你的AppsController中你可以这样做:

public ActionResult GetAgeGroupsWithApps() {
 var ageGroups = _context.AgeGroups
     .Include(ageGroup => ageGroup.Apps)
     .OrderBy(ageGroup => ageGroup.Id)
     .ToList();

 foreach(var ageGroup in ageGroups) {
  foreach(var app in ageGroup.Apps) {
   app.AgeGroup = null;
  }
 }

 return Json(ageGroups);
}

首先,我们包含AgeGroups Apps集合,并按照其ID进行排序。

有趣的是,现在我们有了AgeGroups列表,每个AgeGroup都有一个App对象集合,每个App对象都有一个对AgeGroup的引用。

如果您尝试将其序列化为JSON,则序列化程序将在对象之间的引用之后无休止地陷入循环。为了避免这种情况,我们遍历每个AgeGroup中的Apps,并且对于每个App对象,我们将AgeGroup引用设置为null。

当您这样做时,您可以毫无问题地序列化ageGroups集合。它将返回具有嵌套关联应用程序的AgeGroup对象的JSON数组。

希望这会对你有所帮助。

答案 3 :(得分:1)

我不得不使用_context.Apps,因为您的AgeGroup类中没有Apps导航集合。 但这应该有效。

_context.AgeGroups 
.OrderBy(t=> GroupOrder)
.Select(t=> new AppFormViewModel 
{
      App = t,
      AgeGroup = _context.Apps.Where(x=> c.AgeGroupId == t.Id)
      .Select(x=> new 
      {
          AppIcon = x.AppIcon,
          AppStoreURL = x.StoreURL
      }).AsEnumerable()
}.ToList();

答案 4 :(得分:0)

这是两个彼此之间具有关联关系的类的经典场景。请仔细检查关联聚合和组合的定义,以便在将来创建类时明确了解。按照我的方式解决问题解决它首先我将开始制作它的骨架。

public class AgeGroup 
{
    //Age Group Class 
    [JsonProperty("id")]
    public Guid? Id { get; set; }
    [Jsonproperty("AgeGroup")]
    public string AgeGroupName { get; set; }
    [JsonProperty("App")]
    public List<Appclass> app { get; set; }

}

public class Appclass 
{
    [JsonProperty("id")]
    public Guid? Id { get; set; }
    [Jsonproperty("AppName")]
    public string AppName { get; set; }
}

string yourjsonMethod(List<AgeGroup> ageGroup)
{
    string json=JsonConvert.SerializeObject(agegroup);
    return json;          
}

List<AgeGroup> yourmethod2(string json){
    List<AgeGroup> list=JsonConvert.DeserializeObject<List<AgeGroup>>(json);
    return list;
}

希望这有帮助:)