如何通过从.net中的用户获取列来从数据库中选择多列

时间:2014-09-06 12:53:46

标签: c# .net linq

我的数据库中有一个对象,即有10个属性。 现在我想让用户选择其中的一些(1或2到10个)然后根据用户的选择我制作一个具有用户选择的属性的对象列表 我想到的情况是:

一个带有复选框的页面,显示该项目的属性(列),然后用户选择他们需要的每个属性。

但这是我的问题,如何使选中的复选框作为查询运行? 例如,用户选择col 1,col 2,col 6,col 10,如何编写负责用户选择的查询? 示例我想要这个有意义的短语:

var file2 = file.Select(f => new { "attributes selected by user" }).OrderBy(what user wants)

2 个答案:

答案 0 :(得分:0)

使用DynamicLinq。 (link

扩展方法:

public static T GetValue<T>(this DynamicClass dynamicObject, string propName)
{
    if (dynamicObject == null)
    {
        throw new ArgumentNullException("dynamicObject");
    }

    var type = dynamicObject.GetType();
    var props = type.GetProperties(BindingFlags.Public 
                                 | BindingFlags.Instance 
                                 | BindingFlags.FlattenHierarchy);
    var prop = props.FirstOrDefault(property => property.Name == propName);
    if (prop == null)
    {
        throw new InvalidOperationException("Specified property doesn't exist.");
    }

    return (T)prop.GetValue(dynamicObject, null);
}

public static string ToDynamicSelector(this IList<string> propNames)
{
   if (!propNames.Any()) 
       throw new ArgumentException("You need supply at least one property");
   return string.Format("new({0})", string.Join(",", propNames));
}

用法:

using System.Linq.Dynamic;

// ..

var columns = new[] { "col1", "col2", etc };

var result = context.Files.OrderBy(file => file.Id)
                          .Select(columns.ToDynamicSelector())
                          .Cast<DynamicClass>.ToList();

结果将是DynamiClass个实例的集合,其列将包含所选属性。

DynamicClass获取单个属性:

var columnValue = result.First().GetValue<string>("col1");

如果您想从IEnumerable获取值:

var list = new List<File> { File1, File2, etc.. };

var result = list.AsQueryable().Select( /* the same as above */); 

答案 1 :(得分:0)

Nuget上的System.Linq.Dynamic库是一种方法

[TestMethod]
public void StringyAndDangerous()
{
    var fakePersonDbSet = new List<Person> { new Person() { FirstName = "Some", LastName = "Guy" } }.AsQueryable();
    var attributes = new string[] { "FirstName", "LastName" };
    var selectedFields = String.Join(",", attributes);
    var exprssion = string.Format("new ({0})", selectedFields);
    var result = fakePersonDbSet.Select(exprssion, attributes).Cast<dynamic>().First();
}

但是你放松了类型安全和编译时检查。你可能最好采取另一种方法

[TestMethod]
public void SlowerButSafer()
{
    var fakePersonDbSet = new List<Person> { new Person() { FirstName = "Some", LastName = "Guy" } }.AsQueryable();
    var attributes = new string[] { "FirstName", "LastName" };
    var personPropertylist = CovertToKeyValuePair(fakePersonDbSet.First())
        .Where(c=> attributes.Contains(c.Key))
         .ToArray();            
}

private IEnumerable<KeyValuePair<string, object>> CovertToKeyValuePair<T>(T @object)
{
    var result = new List<KeyValuePair<string, object>>();
    var properties = typeof (T).GetProperties();
    foreach (var property in properties)
    {
        result.Add(new KeyValuePair<string, object>(property.Name, property.GetValue(@object, null)));
    }
    return result;
}

从数据库中提取您不需要的字段以及使用反射时,您的性能都会受到影响,但代码不会出错,并且您不会错误地结束试图选择不存在的列。