如何使用动态 linq 核心 select 并根据另一个字段的条件进行计数
How to select and count base on a condition of another field using dynamic linq core
我正在使用 Entity Framework 和 Dynamic Linq Core 在 运行 时间执行一些动态查询.我有一个关于如何编写动态 linq 语句来输出计数列的问题,其中每列是另一个字段的字段项。
假设我有一个包含 3 列的 table:ID、性别和年龄(假设它们只有 10 多岁)。
ID | Gender | Age
01 | male | 20
02 | female | 30
... some thousands of rows
我想按年龄段统计每个性别(groupBy Gender)的人数。
[{Gender:"male", "20": 120, "30": 200, "40": 300},
{Gender:"female", "20": 300, "30": 200, "40": 1000 }]
我试着按年龄分组,但这并没有给出我想要的上述格式,因为每个性别和年龄组合都会成为一个新的数组项。
var query = db.someDB
.GroupBy("new(Gender, Age)")
.Select("new(Key.Gender as Gender, Key.Age as Age, Count() as value)");
我被限制使用动态 linq 核心,因为在我的实际应用程序中,性别和年龄字段由用户决定,因此他们的字段名称将在 运行 时更改。
你会怎么做?
假设您的查询 returns 以下对象的列表 class
public class Data {
public string Gender { get; set;}
public int Age { get; set;}
public int Value { get; set;}
}
Data results = //query result
var resultsV2 = results.GroupBy(r => r.Gender);
var list = new List<IDictionary<string, object>>();
foreach(var g in resultsV2)
{
IDictionary<string, object> obj = new ExpandoObject();
var data = g.Select(x => x);
obj["Gender"] = $"{g.Key}";
foreach(var d in data)
{
var propName = $"{d.Age}";
obj[propName] = $"{d.Value}";
}
list.Add(obj);
}
string jsonString = JsonConvert.SerializeObject(list);
输入:
new List<Data>
{
new Data() { Gender = "Male", Age = 20, Value = 5 },
new Data() { Gender = "Male", Age = 30, Value = 3 },
new Data() { Gender = "Female", Age = 20, Value = 9 }
};
输出:
[{"Gender":"Male","20":"5","30":"3"},{"Gender":"Female","20":"9"}]
您可以在 LINQ 查询中利用 JSON.Net 类型。 JObject accepts an collection of JProperty and JArray 接受对象集合。这些可以在一个 LINQ 查询中构建:
var table = new List<Person>{
new Person(30,"M"),
new Person(30,"M"),
new Person(30,"M"),
new Person(20,"M"),
new Person(40,"M"),
new Person(30,"V"),
new Person(50,"V"),
new Person(50,"V")
};
var data =
from p1 in table
group p1 by p1.Gender into genderGrp
// Build our JObject
select new JObject(
new JProperty( "Gender", genderGrp.Key)
// and the rest of proprties will the collection of Age
, ( from p2 in genderGrp // over the gender
group p2 by p2.Age into ageGrp
select new JProperty(
ageGrp.Key.ToString() // needs to be a string
, ageGrp.Count())) // aggregate count
);
var jtoken = new JArray(data); // the collection of JObjects goes in the JArray
Console.WriteLine(jtoken.ToString());
结果将是:
[
{
"Gender": "M",
"30": 3,
"20": 1,
"40": 1
},
{
"Gender": "V",
"30": 1,
"50": 2
}
]
我正在使用 Entity Framework 和 Dynamic Linq Core 在 运行 时间执行一些动态查询.我有一个关于如何编写动态 linq 语句来输出计数列的问题,其中每列是另一个字段的字段项。
假设我有一个包含 3 列的 table:ID、性别和年龄(假设它们只有 10 多岁)。
ID | Gender | Age
01 | male | 20
02 | female | 30
... some thousands of rows
我想按年龄段统计每个性别(groupBy Gender)的人数。
[{Gender:"male", "20": 120, "30": 200, "40": 300},
{Gender:"female", "20": 300, "30": 200, "40": 1000 }]
我试着按年龄分组,但这并没有给出我想要的上述格式,因为每个性别和年龄组合都会成为一个新的数组项。
var query = db.someDB
.GroupBy("new(Gender, Age)")
.Select("new(Key.Gender as Gender, Key.Age as Age, Count() as value)");
我被限制使用动态 linq 核心,因为在我的实际应用程序中,性别和年龄字段由用户决定,因此他们的字段名称将在 运行 时更改。
你会怎么做?
假设您的查询 returns 以下对象的列表 class
public class Data {
public string Gender { get; set;}
public int Age { get; set;}
public int Value { get; set;}
}
Data results = //query result
var resultsV2 = results.GroupBy(r => r.Gender);
var list = new List<IDictionary<string, object>>();
foreach(var g in resultsV2)
{
IDictionary<string, object> obj = new ExpandoObject();
var data = g.Select(x => x);
obj["Gender"] = $"{g.Key}";
foreach(var d in data)
{
var propName = $"{d.Age}";
obj[propName] = $"{d.Value}";
}
list.Add(obj);
}
string jsonString = JsonConvert.SerializeObject(list);
输入:
new List<Data>
{
new Data() { Gender = "Male", Age = 20, Value = 5 },
new Data() { Gender = "Male", Age = 30, Value = 3 },
new Data() { Gender = "Female", Age = 20, Value = 9 }
};
输出:
[{"Gender":"Male","20":"5","30":"3"},{"Gender":"Female","20":"9"}]
您可以在 LINQ 查询中利用 JSON.Net 类型。 JObject accepts an collection of JProperty and JArray 接受对象集合。这些可以在一个 LINQ 查询中构建:
var table = new List<Person>{
new Person(30,"M"),
new Person(30,"M"),
new Person(30,"M"),
new Person(20,"M"),
new Person(40,"M"),
new Person(30,"V"),
new Person(50,"V"),
new Person(50,"V")
};
var data =
from p1 in table
group p1 by p1.Gender into genderGrp
// Build our JObject
select new JObject(
new JProperty( "Gender", genderGrp.Key)
// and the rest of proprties will the collection of Age
, ( from p2 in genderGrp // over the gender
group p2 by p2.Age into ageGrp
select new JProperty(
ageGrp.Key.ToString() // needs to be a string
, ageGrp.Count())) // aggregate count
);
var jtoken = new JArray(data); // the collection of JObjects goes in the JArray
Console.WriteLine(jtoken.ToString());
结果将是:
[
{
"Gender": "M",
"30": 3,
"20": 1,
"40": 1
},
{
"Gender": "V",
"30": 1,
"50": 2
}
]