如何在System.Linq.Dynamic中进行Group Concat

时间:2017-09-26 21:37:46

标签: c# dynamic-linq

我正在尝试连接Dynamic linq中的字符串,即常规linq中的string.Join(",", g.Select(i => i.item1))类似

我的动态linq看起来像这样

result.AsEnumerable().AsQueryable().GroupBy("new {it.id.ToString() as entity_id, it[\"item2\"] as item2}", "it").Select("new{key.entity_id, key.item2,
String.Join(\", \", it.Select(it[\"item1\"].ToString())) as item1}")

但它显然不起作用,任何想法 我只想为每个组

添加一个逗号分隔的字符串

修改已添加的数据示例:

只是为了说明数据问题 看起来如何:

Current State

注意:对于PK 1,item1重复两次,因为它来自N:N关系,我需要将它Concat组合在一起说pk

Required State

分辨

我找到了解决此问题的方法,在我的情况下,我需要向System.Linq.Dynamic添加更多功能,按照How to implement SelectMany in System.Linq.Dynamic ExpressionParser由pil0t添加 根据您需要更改的答案

1)签名界面 IEnumerableSignatures 并添加到它:

void Select(string selector); void SelectMany(string selector);/*not needed for this but good to have*/

2)根据他/她的回答添加 ParseAggregate 功能

.... if (signature.Name == "Min" || signature.Name == "Max") { typeArgs = new Type[] { elementType, args[0].Type }; } else if (signature.Name == "Select") { typeArgs = new Type[] { elementType, Expression.Lambda(args[0],innerIt).Body.Type}; } else if (signature.Name == "SelectMany") { var type = Expression.Lambda(args[0], innerIt).Body.Type; var interfaces = type.GetInterfaces().Union(new[] { type }); Type resultType = interfaces.Single(a => a.Name == typeof(IEnumerable<>).Name).GetGenericArguments()[0]; typeArgs = new Type[] { elementType, resultType }; } ....

3)重新编译添加到项目

4)使用如下:String.Join(\&#34;,\&#34;,选择(它[\&#34; item1 \&#34;]。ToString())

1 个答案:

答案 0 :(得分:0)

如果你使用的是System.Linq.Dynamic,你可以用选择新的这种方式连接

Select("new(name,courseID, (name + courseID.ToString()) as y)")

下面是一个完整的控制台应用程序,您可以测试整个代码

class Program
    {
        static void Main(string[] args)
        {

            List<course> Courses = new List<course>();
            Courses.Add(new course() { name = "CA", courseID = 1 });
            Courses.Add(new course() { name = "CB", courseID = 2 });
            Courses.Add(new course() { name = "CC", courseID = 3 });

            string column_name = "name";
            string column_value = "C";
            string where = string.Format("{0}.Contains(@0)", column_name); 
            var result = Courses.Where(where, column_value).Select("new(name,courseID, (name + courseID.ToString()) as y)").Take(50);   
            foreach (var item in result)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
    }
    public class course
    {
        public string name { get; set; }
        public int courseID { get; set; }
    }