4

ストアドプロシージャによって入力されたDataTableがあり、そのデータテーブルからのコレクションが含まれていますRequests(RequestNumber and Tasks(TaskId)。タスクで最初のリクエスト番号に到達したら、それをリストに追加し、次にデータ行を追加して、リストをチェックして存在するかどうかを確認します(if(dr["RequestNumber"].ToString() != acList[i].RequestNumber))存在する場合はデータ行を削除し、存在しない場合は追加しますリスト。

これは順番にうまく機能しますが、データ行とリストが1つずれている場合は、行を追加できます。値がリストに存在するかどうかを見つける方法は他にありますか。

前もって感謝します。

foreach (DataRow dRow in dt.Rows)
{
    DataRow dr = dt.NewRow();
    dr["Project"] = dRow["Project"];
    dr["RequestNumber"] = dRow["RequestNumber"];
    dr["RequestId"] = dRow["RequestId"];
    dr["TaskType"] = dRow["TaskType"];
    dr["TaskId"] = dRow["TaskId"];
    dr["TaskStatus"] = dRow["TaskStatus"];
    dr["AssignedTo"] = dRow["AssignedTo"];
    dr["DateDue"] = dRow["DateDue"];


    if (acList.Count == 0)
    {
        acList.Add(new AssignedClass
        {
            Project = dr["Project"].ToString(),
            RequestNumber = dr["RequestNumber"].ToString(),
            RequestId = dr["RequestId"].ToString(),
            TaskType = dr["TaskType"].ToString(),
            TaskId = dr["TaskId"].ToString(),
            TaskStatus = dr["TaskStatus"].ToString(),
            AssignedTo = dr["AssignedTo"].ToString(),
            DateDue = dr["DateDue"].ToString()
        });
    }

    else
    {
        for (int i = 0; i < acList.Count; i++)
        {

        if(dr["RequestNumber"].ToString() != acList[i].RequestNumber)
        {
            acList.Add(new AssignedClass
            {
                Project = dr["Project"].ToString(),
                RequestNumber = dr["RequestNumber"].ToString(),
                RequestId = dr["RequestId"].ToString(),
                TaskType = dr["TaskType"].ToString(),
                TaskId = dr["TaskId"].ToString(),
                TaskStatus = dr["TaskStatus"].ToString(),
                AssignedTo = dr["AssignedTo"].ToString(),
                DateDue = dr["DateDue"].ToString()
            });
        }
        else
        {
            dr.Delete();
        }
      }
    }
4

4 に答える 4

5

LINQを使用すると、一致するものがあるかどうかを確認するのと同じくらい簡単です。

if ( !acList.Any(a => a.RequestNumber == dr["RequestNumber"].ToString() )
    acList.Add( ... );

また、最初に割り当てたコードにはdRow目的drがないようです。dRowコードの残りの部分全体で直接使用してください。そして、私はあなたが特別な場合として扱いたいとは思わない。(acList.Count == 0)なぜなら、それはあなたがあなたの論理を複製しなければならず、したがって同じコードの2つの別々のコピーを維持しなければならないからである。したがって、すべてを正しく理解していれば、この簡略化されたコードは同じことを達成するはずです。

foreach (DataRow dRow in dt.Rows)
{
    if ( !acList.Any(a => a.RequestNumber == dRow["RequestNumber"].ToString() )
    {
        acList.Add(new AssignedClass
        {
            Project = dRow["Project"].ToString(),
            RequestNumber = dRow["RequestNumber"].ToString(),
            RequestId = dRow["RequestId"].ToString(),
            TaskType = dRow["TaskType"].ToString(),
            TaskId = dRow["TaskId"].ToString(),
            TaskStatus = dRow["TaskStatus"].ToString(),
            AssignedTo = dRow["AssignedTo"].ToString(),
            DateDue = dRow["DateDue"].ToString()
        });
    }
}
于 2013-03-01T14:55:46.107 に答える
2

これはLINQのメソッドにとって素晴らしい仕事ですが、実装Unionが必要です。IEqualityComparer<AssignedClass>これを頻繁に行わない限り、コーディングする価値はおそらくありません(適切に行われた場合は10行ですが)。ただし、これは役立ちます。

acList = acList
    .Concat(from row in dt.Rows
            from ac in acList
            where ac.RequestNumber != row["RequestNumber"].ToString()
            select AssignedClassFromDataRow(row))
    .ToList();

どこ

private static AssignedClass AssignedClassFromDataRow(DataRow row)
{
    // maybe some checks...
    return new AssignedClass
    {
        Project = dRow["Project"].ToString(),
        RequestNumber = dRow["RequestNumber"].ToString(),
        RequestId = dRow["RequestId"].ToString(),
        TaskType = dRow["TaskType"].ToString(),
        TaskId = dRow["TaskId"].ToString(),
        TaskStatus = dRow["TaskStatus"].ToString(),
        AssignedTo = dRow["AssignedTo"].ToString(),
        DateDue = dRow["DateDue"].ToString()
    }
}

ハッシュベースのソリューションよりも少し時間が複雑ですが、実装するには十分に単純です。

編集:

ハッシュによって提供される追加のパフォーマンスが実際に必要な場合は、EqualityComparerを作成できます(ただし、これらのガイドラインに注意してください)。このようなソリューションは、最終的には次のようになります。

acList = acList
    .Union(
        dt.Rows.Select(AssignedClassFromDataRow),
        new MyAssignedClassRequestNumberComparer())
    .ToList();
于 2013-03-01T15:06:50.103 に答える
0

を使用できHashSet<AssignedClass>ます。必要なのは、渡されたオブジェクトのプロパティIEqualityComarer<AssignedClass>をチェックするカスタムを作成し、のコンストラクターでこの比較子のインスタンスを渡すことだけです。RequestNumberHashSet

編集

可能な実装は次のIEqualityComarer<AssignedClass>とおりです。

public class AssignedClassComparer : IEqualityComparer<AssignedClass>
{
    public bool Equals(AssignedClass x, AssignedClass y)
    {
        return x.RequestNumber == y.RequestNumber;
    }

    public int GetHashCode(AssignedClass obj)
    {
        return obj.RequestNumber.GetHashCode();
    }
}

EDIT2: または、HashSetを使用して、行を列挙しながらキーのみを格納することもできます。

var keys = new HashSet<string>();

foreach (DataRow dRow in dt.Rows)
{
    if (keys.Add(dRow["RequestNumber"].ToString()))
    {
        acList.Add(new AssignedClass
        {
            Project = dRow["Project"].ToString(),
            RequestNumber = dRow["RequestNumber"].ToString(),
            RequestId = dRow["RequestId"].ToString(),
            TaskType = dRow["TaskType"].ToString(),
            TaskId = dRow["TaskId"].ToString(),
            TaskStatus = dRow["TaskStatus"].ToString(),
            AssignedTo = dRow["AssignedTo"].ToString(),
            DateDue = dRow["DateDue"].ToString()
        });
    }
}
于 2013-03-01T14:51:08.280 に答える
0

linqのオプションを使用し、最初のコードブロックと0エントリのチェックが少し冗長に見えることを考慮に入れます。プロセスは要約すると

var distinctRows = dt.Rows.GroupBy(x => x["RequestNumber"]).Select(x => x.First());
acList.AddRange(distinctRows.Select(x => x.MapToAssignedClass());


// Added Mapping method for readability
public static AssignedClass MapToAssignedClass(this DataRow dr)
{
    return new AssignedClass
    {
        Project = dr["Project"].ToString(),
        RequestNumber = dr["RequestNumber"].ToString(),
        RequestId = dr["RequestId"].ToString(),
        TaskType = dr["TaskType"].ToString(),
        TaskId = dr["TaskId"].ToString(),
        TaskStatus = dr["TaskStatus"].ToString(),
        AssignedTo = dr["AssignedTo"].ToString(),
        DateDue = dr["DateDue"].ToString()
    });
}
于 2013-03-01T15:04:56.427 に答える