it-swarm.com.de

Datable select mit mehreren Bedingungen

Ich habe eine Datentabelle mit 4 Spalten A, B, C und D, so dass eine bestimmte Kombination von Werten für Spalte A, B und C in der Datentabelle eindeutig ist.

Ziel: Um den Wert von Spalte D für eine gegebene Kombination von Werten für Spalte A, B und C zu ermitteln.

Ich denke, das Durchlaufen von Datenreihen sollte dies tun. Gibt es eine Möglichkeit, Datatable.Select () zu verwenden, um dies zu erreichen? Um genauer zu sein - kann ich mehrere Bedingungen im Auswahlfilter haben, d. H. Einen logischen UND-Operator, der die Bedingungen für jede der Spalten A, B und C verbindet.

41
Arnkrishn

Ja, die Methode DataTable.Select unterstützt boolesche Operatoren auf dieselbe Weise, wie Sie sie in einer "echten" SQL-Anweisung verwenden würden:

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

Siehe DataColumn.Expression in MSDN für die Syntax, die von der Select-Methode von DataTable unterstützt wird.

99

Müssen Sie DataTable.Select() verwenden? Ich ziehe es vor, eine linq-Abfrage für solche Dinge zu schreiben. 

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");
35
womp

Ich habe festgestellt, dass zu viele und falsche Ergebnisse liefern würden (für .NET 1.1 trotzdem).

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

In meinem Fall war A das 12. Feld in einer Tabelle, und die Auswahl ignorierte es effektiv.

Aber wenn ich es tat

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

Der Filter hat richtig funktioniert!

6
JLWarlow

Versuche dies,
Ich denke, das ist eine der einfachen Lösungen.

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

Stellen Sie sicher, dass die Kombination der Werte für Spalte A, B und C in der Datentabelle eindeutig ist.

5
NNNN
    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
Guaroa Mendez
Dim dr As DataRow()


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

Wobei A, B, C die Spaltennamen sind, wobei der zweite Parameter für den Sortierausdruck steht

1
Amit Agrawal

Wenn Sie wirklich nicht auf viele nervige Fehler stoßen möchten (datediff und dergleichen können unter anderem nicht in DataTable.Select ausgewertet werden, und selbst wenn Sie DataTable.AsEnumerable vorschlagen, haben Sie Schwierigkeiten, DateTime-Felder auszuwerten.

1) Modellieren Sie Ihre Daten (erstellen Sie eine Klasse mit DataTable-Spalten).

Beispiel

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

2) Fügen Sie diese Hilfsklasse Ihrem Code hinzu

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) Konvertieren Sie einfach Ihre DataTable (dt) in eine Liste von Objekten mit folgendem Code:

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

4) viel Spaß beim Verwenden von Linq ohne das ärgerliche row.Field<type>-Bit, das Sie verwenden müssen, wenn Sie AsEnumerable verwenden

Beispiel

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