当前位置:编程学习 > C#/ASP.NET >>

LINQ如何查询动态的字段?

例如我有一张表tb_info,结构如下:

现在我要写一个这样的方法,根据字段名返回查询值,例如
public string return(int id,string field) 
{ ??? }
如果调用方法,例如:
string  a = return(3,add),那么a = 地址3;
string  a = return(4,tel),那么返回值为电话4....
在SQL里面是可以拼接字符串实现。
string sql = “select ” + field + "from tb_info where id =" + id; 
然后执行,但是linq如何实现呢?求解答?这个方法里面如何写? --------------------编程问答-------------------- 用反射 http://blog.csdn.net/q107770540/article/details/6133484

或Dynamic LINQ :
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx --------------------编程问答-------------------- 我用反射实现了,谢谢,灰常感谢!
--------------------编程问答-------------------- C# 4.0不需要反射了。 --------------------编程问答-------------------- 自己构造表达式树就可以,你等下,我写个给你。 --------------------编程问答--------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace ConsoleApplication1
{
    class MyData
    {
        public int ID { get; set; }
        public string Address { get; set; }
        public string TelNumber { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            List<MyData> list = new List<MyData>() 
            {
                new MyData() { ID = 1, Address = "beijing", TelNumber = "123" },
                new MyData() { ID = 2, Address = "shanghai", TelNumber = "456" },
                new MyData() { ID = 3, Address = "guangzhou", TelNumber = "789" },
            };
            var query1 = FindData(list, 1, "Address").First();
            Console.WriteLine(query1);
            var query2 = FindData(list, 3, "TelNumber").First();
            Console.WriteLine(query2);
        }
        static List<string> FindData(List<MyData> data, int id, string fieldname)
        { 
            var param = Expression.Parameter(typeof(MyData));
            var lambda = Expression.Lambda(Expression.MakeMemberAccess(param, typeof(MyData).GetProperty(fieldname)), param);
            return data.Where(x => x.ID == id).Select(lambda.Compile() as Func<MyData, string>).ToList();
        }
    }
}
--------------------编程问答-------------------- 顶老曹

如果能将FindData写成扩展方法,用起来就更方便了 --------------------编程问答--------------------
引用 6 楼 q107770540 的回复:
顶老曹

如果能将FindData写成扩展方法,用起来就更方便了


嗯,反射对于大数据来说有些慢的,因为Linq查询需要对每一条都操作一次。估计微软也是意识到了这个问题,才在.NET 4.0中增加了MemberAccess表达式。事实上,这个操作在IL层面早就可以实现,只是C#没有等效的语法(如果要有,应该类似typeof叫fieldof)。 --------------------编程问答-------------------- 参照这篇文章里面有~http://www.cnblogs.com/daviddai/archive/2013/03/09/2952087.html --------------------编程问答-------------------- 现在有个新框架可以解决这个问题了。http://esql.codeplex.com --------------------编程问答-------------------- 反射其实很简单。例如
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        public static int XY;

        static void Main(string[] args)
        {
            var datas = new List<User>();
            datas.Add(new User { A = "a", B = 1, C = 1.1 });
            datas.Add(new User { A = "b", B = 2, C = 2.1 });
            datas.Add(new User { A = "a", B = 3, C = 3.1 });
            var u = "B";
            var v = 1;
            var p = typeof(User).GetProperty(u);
            var result = from x in datas
                         where x.A == "a"
                         let y = (int)p.GetValue(x)
                         where y > v
                         select x;
            foreach (var x in result)
                Console.WriteLine("A={0}, B={1}, C={2}", x.A, x.B, x.C);
            Console.ReadLine();
        }

        private static void abc()
        {
            XY = 99;
        }
    }

    public class User
    {
        public string A { get; set; }
        public int B { get; set; }
        public double C { get; set; }
    }
}


这里,变量v和u分别代表要查询的值和字段名。

如果没有经过测试得到特别有利的证据证明值得学习,我们其实用不着去找什么“新框架”。 --------------------编程问答-------------------- 如果你大量地反复调用相同的函数,那么可以将GetProperty(或者GetField)方法的结果保存起来。毕竟它是不变的,没有必要重复执行。例如
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var datas = new List<User>();
            datas.Add(new User { id = 3, A = "a", B = "1", C = 1.1 });
            datas.Add(new User { id = 4, A = "b", B = "2", C = 2.1 });
            datas.Add(new User { id = 5, A = "a", B = "3", C = 3.1 });
            Console.WriteLine(returnX(datas, 3, "A"));
            Console.WriteLine(returnX(datas, 3, "B"));
            Console.WriteLine(returnX(datas, 4, "B"));
            Console.WriteLine(returnX(datas, 4, "A"));
            Console.ReadLine();
        }

        private static Dictionary<string, FieldInfo> FieldDescriptors = new Dictionary<string, FieldInfo>();

        private static string returnX(IEnumerable<User> datas, int id, string field)
        {
            var t = typeof(User);
            var key = string.Format("类型{0}的字段{1}", t.FullName, field);
            FieldInfo f;
            if (!FieldDescriptors.TryGetValue(key, out f))
            {
                f = t.GetField(field);
                FieldDescriptors.Add(key, f);
            }
            return (string)f.GetValue(datas.First(x => x.id == id));
        }
    }

    public class User
    {
        public int id;
        public string A;
        public string B;
        public double C;
    }
}

--------------------编程问答--------------------
引用 5 楼 caozhy 的回复:
C# code?12345678910111213141516171819202122232425262728293031323334353637using System;using System.Collections.Generic;using System.Linq;using System.Linq.Expressions;using System.Text; n……


不知道有没有考虑过
List<MyData> list = new List<MyData>();这个List和,MyData类型你要让楼主怎么得到?
是要先拼SQL从数据库查出数据集,然后通过反射映射到MyData的对应属性上?
而且,貌似楼主用的是Access,玩不了EF吧? --------------------编程问答-------------------- 我也正在找这个问题!
补充:.NET技术 ,  LINQ
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,