具有多个条件的数据表选择

时间:2010-01-02 08:07:03

标签: c# select datatable

我有一个包含4列A,B,C和D的数据表,因此A,B和C列的特定值组合在数据表中是唯一的。

目标:为列A,B和C的给定值组合查找列D的值。

我想循环数据行集应该这样做。有没有办法使用Datatable.Select()来实现这一目标?更具体一点 - 我可以在选择过滤器中有多个条件,即每个列A,B和C的逻辑AND运算符连接条件。

7 个答案:

答案 0 :(得分:103)

是的,DataTable.Select方法支持布尔运算符的方式与在“真正的”SQL语句中使用布尔运算符的方式相同:

DataRow[] results = table.Select("A = 'foo' AND B = 'bar' AND C = 'baz'");

有关DataTable的Select方法支持的语法,请参阅DataColumn.Expression in MSDN

答案 1 :(得分:38)

你必须使用DataTable.Select()吗?我更喜欢为这种事写一个linq查询。

var dValue=  from row in myDataTable.AsEnumerable()
             where row.Field<int>("A") == 1 
                   && row.Field<int>("B") == 2 
                   && row.Field<int>("C") == 3
             select row.Field<string>("D");

答案 2 :(得分:6)

我发现有太多而且会返回不正确的结果(无论如何都是针对.NET 1.1)

DataRow[] results = table.Select("A = 'foo' AND B = 'bar' AND C = 'baz' and D ='fred' and E = 'marg'"); 

在我的情况下,A是表格中的第12个字段,而select实际上忽略了它。

但是,如果我做了

DataRow[] results = table.Select("A = 'foo' AND (B = 'bar' AND C = 'baz' and D ='fred' and E = 'marg')"); 

过滤器工作正常!

答案 3 :(得分:5)

试试这个,
我认为,这是一个简单的解决方案。

int rowIndex = table.Rows.IndexOf(table.Select("A = 'foo' AND B = 'bar' AND C = 'baz'")[0]);
string strD= Convert.ToString(table.Rows[rowIndex]["D"]);

确保,A,B和C列的值组合在数据表中是唯一的。

答案 4 :(得分:2)

    protected void FindCsv()
    {
        string strToFind = "2";

        importFolder = @"C:\Documents and Settings\gmendez\Desktop\";

        fileName = "CSVFile.csv";

        connectionString= @"Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq="+importFolder+";Extended Properties=Text;HDR=No;FMT=Delimited";
        conn = new OdbcConnection(connectionString);

        System.Data.Odbc.OdbcDataAdapter  da = new OdbcDataAdapter("select * from [" + fileName + "]", conn);
        DataTable dt = new DataTable();
        da.Fill(dt);

        dt.Columns[0].ColumnName = "id";

        DataRow[] dr = dt.Select("id=" + strToFind);

        Response.Write(dr[0][0].ToString() + dr[0][1].ToString() + dr[0][2].ToString() + dr[0][3].ToString() + dr[0][4].ToString() + dr[0][5].ToString());
    }

答案 5 :(得分:1)

Dim dr As DataRow()


dr = dt.Select("A="& a & "and B="& b & "and C=" & c,"A",DataViewRowState.CurrentRows)

其中A,B,C是列名 其中第二个参数用于排序表达式

答案 6 :(得分:0)

如果你真的不想遇到很多令人讨厌的错误(在{ "test": { "aliases": {}, "mappings": { "attachment": { "properties": { "analyzer": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "field_statistics": { "type": "boolean" }, "fields": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "file": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, ... } 之内就可以评估日期和其他问题,即使你按照建议使用{{1你将无法评估DateTime字段)执行以下操作:

1)为您的数据建模(使用DataTable列创建一个类)

实施例

DataTable.Select

2)将此助手类添加到您的代码

DataTable.AsEnumerable

3)使用以下代码轻松将public class Person { public string PersonId { get; set; } public DateTime DateBorn { get; set; } } (dt)转换为对象列表:

public static class Extensions
{
/// <summary>
/// Converts datatable to list<T> dynamically
/// </summary>
/// <typeparam name="T">Class name</typeparam>
/// <param name="dataTable">data table to convert</param>
/// <returns>List<T></returns>
public static List<T> ToList<T>(this DataTable dataTable) where T : new()
{
    var dataList = new List<T>();

    //Define what attributes to be read from the class
    const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;

    //Read Attribute Names and Types
    var objFieldNames = typeof(T).GetProperties(flags).Cast<PropertyInfo>().
        Select(item => new
        {
            Name = item.Name,
            Type = Nullable.GetUnderlyingType(item.PropertyType) ?? item.PropertyType
        }).ToList();

    //Read Datatable column names and types
    var dtlFieldNames = dataTable.Columns.Cast<DataColumn>().
        Select(item => new {
            Name = item.ColumnName,
            Type = item.DataType
        }).ToList();

    foreach (DataRow dataRow in dataTable.AsEnumerable().ToList())
    {
        var classObj = new T();

        foreach (var dtField in dtlFieldNames)
        {
            PropertyInfo propertyInfos = classObj.GetType().GetProperty(dtField.Name);

            var field = objFieldNames.Find(x => x.Name == dtField.Name);

            if (field != null)
            {

                if (propertyInfos.PropertyType == typeof(DateTime))
                {
                    propertyInfos.SetValue
                    (classObj, ConvertToDateTime(dataRow[dtField.Name]), null);
                }
                else if (propertyInfos.PropertyType == typeof(int))
                {
                    propertyInfos.SetValue
                    (classObj, ConvertToInt(dataRow[dtField.Name]), null);
                }
                else if (propertyInfos.PropertyType == typeof(long))
                {
                    propertyInfos.SetValue
                    (classObj, ConvertToLong(dataRow[dtField.Name]), null);
                }
                else if (propertyInfos.PropertyType == typeof(decimal))
                {
                    propertyInfos.SetValue
                    (classObj, ConvertToDecimal(dataRow[dtField.Name]), null);
                }
                else if (propertyInfos.PropertyType == typeof(String))
                {
                    if (dataRow[dtField.Name].GetType() == typeof(DateTime))
                    {
                        propertyInfos.SetValue
                        (classObj, ConvertToDateString(dataRow[dtField.Name]), null);
                    }
                    else
                    {
                        propertyInfos.SetValue
                        (classObj, ConvertToString(dataRow[dtField.Name]), null);
                    }
                }
            }
        }
        dataList.Add(classObj);
    }
    return dataList;
}

private static string ConvertToDateString(object date)
{
    if (date == null)
        return string.Empty;

    return HelperFunctions.ConvertDate(Convert.ToDateTime(date));
}

private static string ConvertToString(object value)
{
    return Convert.ToString(HelperFunctions.ReturnEmptyIfNull(value));
}

private static int ConvertToInt(object value)
{
    return Convert.ToInt32(HelperFunctions.ReturnZeroIfNull(value));
}

private static long ConvertToLong(object value)
{
    return Convert.ToInt64(HelperFunctions.ReturnZeroIfNull(value));
}

private static decimal ConvertToDecimal(object value)
{
    return Convert.ToDecimal(HelperFunctions.ReturnZeroIfNull(value));
}

private static DateTime ConvertToDateTime(object date)
{
    return Convert.ToDateTime(HelperFunctions.ReturnDateTimeMinIfNull(date));
}

}
public static class HelperFunctions
{

public static object ReturnEmptyIfNull(this object value)
{
    if (value == DBNull.Value)
        return string.Empty;
    if (value == null)
        return string.Empty;
    return value;
}
public static object ReturnZeroIfNull(this object value)
{
    if (value == DBNull.Value)
        return 0;
    if (value == null)
        return 0;
    return value;
}
public static object ReturnDateTimeMinIfNull(this object value)
{
    if (value == DBNull.Value)
        return DateTime.MinValue;
    if (value == null)
        return DateTime.MinValue;
    return value;
}
/// <summary>
/// Convert DateTime to string
/// </summary>
/// <param name="datetTime"></param>
/// <param name="excludeHoursAndMinutes">if true it will execlude time from datetime string. Default is false</param>
/// <returns></returns>
public static string ConvertDate(this DateTime datetTime, bool excludeHoursAndMinutes = false)
{
    if (datetTime != DateTime.MinValue)
    {
        if (excludeHoursAndMinutes)
            return datetTime.ToString("yyyy-MM-dd");
        return datetTime.ToString("yyyy-MM-dd HH:mm:ss.fff");
    }
    return null;
}
}

4)使用Linq玩得开心,没有使用DataTable

时必须使用的令人讨厌的List<Person> persons = Extensions.ToList<Person>(dt);

实施例

row.Field<type>