Datatable select avec plusieurs conditions

j'ai un datatable avec 4 colonnes A, B, C et D Tel qu'une combinaison particulière de valeurs pour les colonnes A, B et c est unique dans le datatable.

Objectif: Pour trouver la valeur de la colonne D, pour une combinaison donnée de valeurs de la colonne A, B et C.

je suppose que boucler sur l'ensemble des lignes de données devrait le faire. Est-il possible d'utiliser Datatable.Sélectionnez() pour accomplir cette? Pour être plus précis-puis - je avoir plusieurs conditions dans le filtre select i.e. des conditions de connexion logiques et opératrices pour chacune des colonnes A, B et C.

38
demandé sur hims056 2010-01-02 11:07:03

7 réponses

Oui,DataTable.Select la méthode supporte les opérateurs booléens de la même manière que vous les utiliseriez dans une "vraie" instruction SQL:

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

Voir DataColumn.Expression in MSDN pour la syntaxe supportée parSelect méthode.

91
répondu Michael Petrotta 2010-01-02 08:25:22

avez-vous d'utiliser DataTable.Select()? Je préfère écrire une requête linq pour ce genre de chose.

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");
32
répondu womp 2017-09-19 09:28:42

j'ai trouvé qu'avoir trop d'and's retournerait des résultats incorrects (pour .net 1.1 de toute façon)

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

dans mon cas A était le 12e champ dans une table et le select l'ignorait effectivement.

Cependant si je l'ai fait

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

Le filtre a fonctionné correctement!

6
répondu JLWarlow 2010-05-06 10:35:14

Essayez ceci,

Je pense que c'est une des solutions simples.

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

assurez-vous, la combinaison des valeurs pour les colonnes A, B et c est unique dans le datatable.

5
répondu NNNN 2011-11-15 08:32:44
    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());
    }
2
répondu Guaroa Mendez 2011-08-24 10:08:04
Dim dr As DataRow()


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

où A, B,C sont les noms des colonnes où le second paramètre est pour l'expression sort

1
répondu Amit Agrawal 2015-06-15 09:51:15

si vous ne voulez vraiment pas courir dans beaucoup d'erreurs ennuyeuses (datediff et tels ne peuvent pas être évalués dans DataTable.Select entre autres choses et même si vous faites comme Utilisation suggérée DataTable.AsEnumerable vous aurez de la difficulté à évaluer les champs DateTime) faites ce qui suit:

1) modélisez vos données (créez une classe avec des colonnes de données)

Exemple

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

2) Ajoutez cette classe helper à votre code

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) convertissez facilement votre DataTable (dt) à une Liste de les objets avec le code suivant:

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

4) amusez-vous en utilisant Linq sans lesrow.Field<type> bits, vous devez utiliser lors de l'utilisation de AsEnumerable

Exemple

var personsBornOn1980 = persons.Where(x=>x.DateBorn.Year == 1980);
0
répondu JAnton 2018-01-31 16:34:38