代码之家  ›  专栏  ›  技术社区  ›  Arnkrishn

多条件数据表选择

  •  41
  • Arnkrishn  · 技术社区  · 16 年前

    我有一个数据表,有4列A、B、C和D,这样A、B和C列的特定值组合在数据表中是唯一的。

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

    我想循环遍历一组数据行应该可以做到这一点。是否有方法使用dataTable.select()来完成此操作?更具体地说,我可以在选择过滤器中有多个条件,即A、B和C列的逻辑和运算符连接条件。

    7 回复  |  直到 8 年前
        1
  •  99
  •   Michael Petrotta user3140870    16 年前

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

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

    DataColumn.Expression in MSDN 数据表支持的语法 Select 方法。

        2
  •  35
  •   Tamilselvan K    8 年前

    你必须用吗 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");
    
        3
  •  6
  •   John Warlow    15 年前

    我发现过多的和会返回错误的结果(对于.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')"); 
    

    过滤器工作正常!

        4
  •  5
  •   NNNN    14 年前

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

    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列的值组合在数据表中是唯一的。

        5
  •  2
  •   Edwin de Koning Umair Baig    14 年前
        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());
        }
    
        6
  •  1
  •   josliber Martin Ballet    10 年前
    Dim dr As DataRow()
    
    
    dr = dt.Select("A="& a & "and B="& b & "and C=" & c,"A",DataViewRowState.CurrentRows)
    

    其中a、b、c是列名 其中第二个参数用于排序表达式

        7
  •  0
  •   JAnton    8 年前

    如果你真的不想遇到很多恼人的错误(datediff等不能在 DataTable.Select 除此之外,即使你按照建议使用 DataTable.AsEnumerable 计算日期时间字段时会遇到问题)请执行以下操作:

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

    例子

    public class Person
    {
    public string PersonId { get; set; }
    public DateTime DateBorn { get; set; }
    }
    

    2)将这个助手类添加到代码中

    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;
    }
    }
    

    3)轻松转换 DataTable (dt)到具有以下代码的对象列表:

    List<Person> persons = Extensions.ToList<Person>(dt);
    

    4)在使用LINQ的同时,不要让人讨厌。 row.Field<type> 使用时必须使用的位 AsEnumerable

    例子

    var personsBornOn1980 = persons.Where(x=>x.DateBorn.Year == 1980);