2014-05-09 2 views
1

2 개의 DataTable이 있습니다. OriginalEntity 및 엔터티 인터페이스 응용 프로그램이 Entity DataTable의 행을 수정합니다. 저장하는 동안 수정되었거나 OrigianlEntity와 다른 DataRow를 확인하려고합니다. 예를 들어 비교하는 동안 몇 개의 입력란을 제외해야합니다. 수정 된 날짜 및 기타 감사 필드. 현재 나는이 같은 데이터 테이블의 각 행을 반복하고있다 :일부 열을 제외하고 2 개의 DataRow를 비교하십시오.

List<string> auditFields = new List<string>(){"createdon","modifiedon"}; 
string IdentityKeyName = "id"; 
object ent,orgEnt; 
foreach(string columnName in columnList) // ColumnList is List of columns available in datatable 
{ 
    foreach(DataRow dr in Entity.Rows) 
    { 
     ent = dr[columnName]; 
     orgEnt = OriginalEntity.Select(IdentityKeyName + " = " + dr[IdentityKeyName].ToString())[0][columnName]; 
     if(!ent.Equals(orgEnt) && !auditFields.Contains(columnName)) 
     { 
      isModified = true; 
      break; 
     } 
    } 
} 

난 그냥 효율적인 방법은 위 달성하고자합니다. 제발 제안 해주세요.

감사합니다 귀하의 제안에 대한 모든 사람, 이것은 내 (I은 기본 키가 정의하지 않는 한)

해결 방법 : 열이 비교하지만 루프해야 할 것

public bool isModified(DataTable dt1, DataTable dt2, string IdentityKeyName) 
{ 
    bool isModified = false; 
    List<string> auditFields = new List<string>() { "createdon", "modifiedon" }; 
    isModified = isModified || (dt1.Rows.Count != dt2.Rows.Count); 
    if(!isModified) 
    { 
     //Approach takes 150 ms to compare two datatable of 10000 rows and 24 columns each 
     DataTable copyOriginalEntity = dt1.Copy(); 
     DataTable copyEntity = dt2.Copy(); 

     //Exclude field you don't want in your comparison -- It was my main task 
     foreach(string column in auditFields) 
     { 
      copyOriginalEntity.Columns.Remove(column); 
      copyEntity.Columns.Remove(column); 
     } 
     for(int i=0;i<copyOriginalEntity.Rows.Count;i++) 
     { 
      var origItems = copyOriginalEntity.Rows[i].ItemArray; 
      var entityItem = copyEntity.Select(IdentityKeyName + " = " + copyOriginalEntity.Rows[i][dentityKeyName].ToString())[0].ItemArray; 
      if(string.Concat(origItems) != string.Concat(entityItem)){ isModified = true; break; } 
     } 
    } 
    return isModified; 
} 
+0

무엇이'columnName'입니까? 결국 원하는 결과는 무엇입니까? 변경된 사항이 있는지 또는 행과 필드를 알고 싶나요? –

+0

'효율적인'이란 무엇을 의미합니까? 더 빠르고, 적은 코드, 또는 다른 것들? – qxg

+0

@TimSchmelter, 수정 된 코드. –

답변

1

. 이 코드는 객체 참조가 동일하면 ent.Equals (orgEnt)을 비교합니다. 이것은 당신이 원하는 것과 같지 않고 당신은 가치를 비교하기를 원합니다.

public bool IsChanged(DataTable original, DataTable source, string idKeyName, params string[] ignoreColumns) 
{ 
    // make sure "key" column exist in both 
    if (!original.Columns.Contains(idKeyName) || !source.Columns.Contains(idKeyName)) 
    { 
     throw new MissingPrimaryKeyException("Primary key column not found."); 
    } 

    // if source rows are not the same as original then something was deleted or added 
    if (source.Rows.Count != original.Rows.Count) 
    { 
     return false; 
    } 

    // Get a list of columns ignoring passed in and key (key will have to be equal to find) 
    var originalColumns = 
     original.Columns.Cast<DataColumn>() 
       .Select(c => c.ColumnName) 
       .Where(n => !ignoreColumns.Contains(n) && n != idKeyName) 
       .ToArray(); 

    // check to make sure same column count otherwise just fail no need to check 
    var sourceColumnsCount = 
     source.Columns.Cast<DataColumn>() 
       .Select(c => c.ColumnName).Count(originalColumns.Contains); 
    if (originalColumns.Length != sourceColumnsCount) 
    { 
     return false; 
    } 

    //Switch to linq 
    var sourceRows = source.AsEnumerable(); 
    return sourceRows.All(sourceRow => 
     { 
      // use select since not real key 
      var originalCheck = original.Select(idKeyName + " = " + sourceRow[idKeyName]); 
      if (originalCheck.Length != 1) 
      { 
       // Couldn't find key or multiple matches 
       return false; 
      } 

      var originalRow = originalCheck.First(); 
      //Since using same array we can use linq's SequenceEqual to compare for us 
      return 
       originalColumns.Select(oc => sourceRow[oc]) 
           .SequenceEqual(originalColumns.Select(oc => originalRow[oc])); 
     }); 
} 

일부 미세 최적화가있을 수 있지만 각 열을 확인해야 할 필요는 없습니다.

+0

감사. 나는 접근 방식을 비교하여 루프를 덜 관리했다. –

관련 문제