使用LINQ列出(和返回)列

时间:2013-10-23 01:06:45

标签: c# wpf entity-framework-5

我有一个记录的SQL表,列有" Col1"," Col2"," Col3"等等...所有都是相同的类型(并且是相同的"事物")

表与这些列之间的关系基本上是一对多。我可以创建另一个表并在它们之间建立关系,但是我有许多不相关的表都与" Col1"," Col2"," Col3"等......这需要我多次复制表格。

我需要一种方法将这些列转换为列表,并将列表元素放回到列中。订购数据无关紧要。如果" Col1"包含A和" Col2"包含B,如果" Col1"包含B和" Col2"更新后包含A.

我画了一幅漂亮的图片来说明

enter image description here

一种非常丑陋的方法,可以将数据重新输入。

int fieldCount = 0;
foreach (string field in MyList)
{
    switch (fieldCount++)
    {
        case 1:
            entityObject.Col1 = field;
            break;
        case 2:
            entityObject.Col2 = field;
            break;
        case 3:
            entityObject.Col3 = field;
            break;
        case 4:
            entityObject.Col4 = field;
            break;
        case 5:
            entityObject.Col5 = field;
            break;
    }

} 

2 个答案:

答案 0 :(得分:2)

您可以使用反射:

//replace object parameter with some base class if possible
public static List<string> GetColumnValues(object item)
{
    return item.GetType().GetProperties()
        .Where(prop => prop.Name.StartsWith("Col") 
            && prop.PropertyType == typeof(string))
        .Select(prop => prop.GetValue(item) as string)
        .ToList();
}

然后设置它们你可以再次使用反射:

//replace object parameter with some base class if possible
public static void GetColumnValues(object item, List<string> values)
{
    foreach(var pair in item.GetType().GetProperties()
        .Where(prop => prop.Name.StartsWith("Col") 
            && prop.PropertyType == typeof(string))
        .Zip(values, (prop, value) => new{prop,value})
    {
        pair.prop.SetValue(item, pair.value);
    }
}

答案 1 :(得分:2)

如果速度很重要,那么最好避免使用反射。一个“整洁”(?)方式是设置一组setter,然后循环遍历:

var setters = new Action<string>[] 
{ 
    val => entityObject.Col1 = val,
    val => entityObject.Col2 = val,
    val => entityObject.Col3 = val,
    val => entityObject.Col4 = val,
    val => entityObject.Col5 = val,
};
for (int i=0 ; i<MyList.Count ; i++)
    setters[i](MyList[i]);

如果你可以获得性能提升,那么反射将产生更少的代码行/更少的重复:

Type type = entityObject.GetType();
PropertyInfo[] props = Enumerable.Range(1, MyList.Count).Select(num => type.GetProperty("Col" + num)).ToArray();
for (int i=0 ; i<MyList.Count ; i++)
    props[i].SetValue(entityObject, MyList[i]);

(当然,像"FastMember"这样的反射也有更快的替代方案。)