none
Динамический запрос LINQ RRS feed

  • Вопрос

  • Привет всем!

    Нарисовывается интересная задачка:

    Можно ли собрать строку запроса как string и выполнить её, примерно так

    string query = "from i in source where .условия . условия.... select i";
    //Каким нибудь макаром выполнить всё это.
    

    Знаю, что за кулисами всё это превратится в цепочку расширяющих методов. Деревья выражений использовать не хочу из-за их громоздкости. Может есть какая-то библиотека преобразований или ещё что-то?  Вопрос наверное глупый, но жутко хочется облегчить себе жизнь. Но из собственного опыта: такое получается редко(Лёгкий хлеб не получается!).


    14 ноября 2011 г. 13:47
    Модератор

Ответы

  • > Можно ли собрать строку запроса как string и выполнить её, примерно такstring query = "from i in source where .условия . условия.... select i"; //Каким нибудь макаром выполнить всё это.

     
    можно с помощью CSharpCodeProvider.
    примерно так:
     
    using System;
    using System.CodeDom;
    using System.CodeDom.Compiler;
    using System.Collections;
    using System.Collections.Generic;
    using System.Dynamic;
    using System.Linq;
    using System.Reflection;
    using System.Windows.Forms;
    using Microsoft.CSharp;
    
    namespace WindowsFormsApplication2
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                var arr = new [] { 1, 2, 3, 4, 5 };
    
                var res1 = LinqHelper.Invoke("from i in src select i*100", arr);
                var lv = new ListView { Parent = this, Dock = DockStyle.Fill };
                foreach(var i in res1)
                    lv.Items.Add(i.ToString());
    
                var res2 = LinqHelper.Invoke("from i in src where i % 2 == 0 select new { Value=i*100 }", arr);
                new DataGrid { Parent = this, Dock = DockStyle.Bottom, Height=200, DataSource = res2.Cast<object>().ToList() };
            }
        }
    
        public static class LinqHelper
        {
            public static IEnumerable Invoke<T>(string code, IEnumerable<T> en)
            {
                var a = Compile(String.Concat(@"
                        using System;
                        using System.Linq;
                        using System.Collections.Generic;
                        public static class Some { public static object Run(IEnumerable<", 
                            typeof(T).FullName, 
                            "> src) { return (", code, "); }}"),
                        "System.dll",
                        "System.Core.dll");
                var t = a.CompiledAssembly.GetType("Some");
                var m = t.GetMethod("Run", BindingFlags.Static | BindingFlags.Public);
                return m.Invoke(null, new object[] { en }) as IEnumerable;
            }
    
            public static CompilerResults Compile(string code, params string[] assemblies)
            {
                var csp = new CSharpCodeProvider();
                var ccu = new CodeCompileUnit();
                var cps = new CompilerParameters();
                cps.ReferencedAssemblies.AddRange(assemblies);
                cps.GenerateInMemory = true;
                return csp.CompileAssemblyFromSource(cps, code);
            }
        }
    }


     
    также см. dynamic query LINQ helper library
     
     
     
    • Предложено в качестве ответа Malobukv 14 ноября 2011 г. 14:59
    • Изменено Malobukv 14 ноября 2011 г. 15:03
    • Помечено в качестве ответа YatajgaModerator 15 ноября 2011 г. 6:36
    14 ноября 2011 г. 14:58
  • Можно ли собрать строку запроса как string и выполнить её, примерно так

    string query = "from i in source where .условия . условия.... select i";
    //Каким нибудь макаром выполнить всё это.
    

    SqlCommand
    • Предложено в качестве ответа Nick Mokhnatov 14 ноября 2011 г. 18:55
    • Помечено в качестве ответа Abolmasov Dmitry 15 ноября 2011 г. 6:31
    14 ноября 2011 г. 15:05
  • Можно использовать Dynamic Linq.

    • Помечено в качестве ответа Abolmasov Dmitry 15 ноября 2011 г. 6:31
    15 ноября 2011 г. 4:10
    Модератор

Все ответы

  • > Можно ли собрать строку запроса как string и выполнить её, примерно такstring query = "from i in source where .условия . условия.... select i"; //Каким нибудь макаром выполнить всё это.

     
    можно с помощью CSharpCodeProvider.
    примерно так:
     
    using System;
    using System.CodeDom;
    using System.CodeDom.Compiler;
    using System.Collections;
    using System.Collections.Generic;
    using System.Dynamic;
    using System.Linq;
    using System.Reflection;
    using System.Windows.Forms;
    using Microsoft.CSharp;
    
    namespace WindowsFormsApplication2
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                var arr = new [] { 1, 2, 3, 4, 5 };
    
                var res1 = LinqHelper.Invoke("from i in src select i*100", arr);
                var lv = new ListView { Parent = this, Dock = DockStyle.Fill };
                foreach(var i in res1)
                    lv.Items.Add(i.ToString());
    
                var res2 = LinqHelper.Invoke("from i in src where i % 2 == 0 select new { Value=i*100 }", arr);
                new DataGrid { Parent = this, Dock = DockStyle.Bottom, Height=200, DataSource = res2.Cast<object>().ToList() };
            }
        }
    
        public static class LinqHelper
        {
            public static IEnumerable Invoke<T>(string code, IEnumerable<T> en)
            {
                var a = Compile(String.Concat(@"
                        using System;
                        using System.Linq;
                        using System.Collections.Generic;
                        public static class Some { public static object Run(IEnumerable<", 
                            typeof(T).FullName, 
                            "> src) { return (", code, "); }}"),
                        "System.dll",
                        "System.Core.dll");
                var t = a.CompiledAssembly.GetType("Some");
                var m = t.GetMethod("Run", BindingFlags.Static | BindingFlags.Public);
                return m.Invoke(null, new object[] { en }) as IEnumerable;
            }
    
            public static CompilerResults Compile(string code, params string[] assemblies)
            {
                var csp = new CSharpCodeProvider();
                var ccu = new CodeCompileUnit();
                var cps = new CompilerParameters();
                cps.ReferencedAssemblies.AddRange(assemblies);
                cps.GenerateInMemory = true;
                return csp.CompileAssemblyFromSource(cps, code);
            }
        }
    }


     
    также см. dynamic query LINQ helper library
     
     
     
    • Предложено в качестве ответа Malobukv 14 ноября 2011 г. 14:59
    • Изменено Malobukv 14 ноября 2011 г. 15:03
    • Помечено в качестве ответа YatajgaModerator 15 ноября 2011 г. 6:36
    14 ноября 2011 г. 14:58
  • Можно ли собрать строку запроса как string и выполнить её, примерно так

    string query = "from i in source where .условия . условия.... select i";
    //Каким нибудь макаром выполнить всё это.
    

    SqlCommand
    • Предложено в качестве ответа Nick Mokhnatov 14 ноября 2011 г. 18:55
    • Помечено в качестве ответа Abolmasov Dmitry 15 ноября 2011 г. 6:31
    14 ноября 2011 г. 15:05
  • Можно использовать Dynamic Linq.

    • Помечено в качестве ответа Abolmasov Dmitry 15 ноября 2011 г. 6:31
    15 ноября 2011 г. 4:10
    Модератор
  • Спасибо большое за ответы! Я тоже хотел копнуть в сторону рефлексии, ну и окончательно решил выбрать этот вариант. Всемогущая рефлексия! А то Dynamiq Linq - не лучший выбор. А облегчить себе жизнь опять не получилось, впрочем, я так и знал.

    15 ноября 2011 г. 6:51
    Модератор