2017-10-26 8 views
1

내용의 유효성을 검사하려고하는데 파일을 Excel에서 처리하고 그 내용을 데이터 테이블에 읽도록 ​​관리했습니다. 각 행을 반복하고 각 특정 행의 중복 행을 Record 클래스 목록으로 결정합니다. 나는 오류를 확인하기 위해 사용자가하고자하는 방법은 다음과데이터 테이블의 특정 레코드에 중복되는 모든 레코드를 가져 오는 가장 효율적인 방법

은 다음과 같습니다

규칙 : 도메인 및 사용자 이름은 데이터 테이블

입력 엑셀 /보기

Domain Username Details 
x  sam1  1234  //row1 
x  jack1 4412  //row2 
x  sam1  1233  //row3 
y  jack1 4442  //row4 
z  jason1 5522  //row5 
x  sam1  8949  //row6 

출력 달라야합니다

유효하지 않은 항목 :

Row Domain Username Details ErrorMessage 
1 x  sam1  1234  Duplicate row for r3, r6 
3 x  sam1  1233  Duplicate row for r1, r6      
6 x  sam1  8949  Duplicate row for r1, r3 

유효한 항목 : 코드에서

Row Domain Username Details 
2  x  jack1 4412 //not duplicate with row4 because different domain 
4  y  jack1 4442 //row4 
5  z  jason1 5522 

내가보기에 사용됩니다 내가 만든 클래스의 목록을 작성하려는 뒤에. 뒤에

public class Record 
    { 
     public long Row { get; set; } 
     public string Domain { get; set; } 
     public string Username { get; set; } 
     public string Details { get; set; } 
     public string ErrorMessage{ get; set; } 
     public bool IsValid { get;set; } 
    } 

코드 :

DataTable excelDataTable = ... //read excel into datatable 
foreach (DataRow row in excelDataTable.Rows) //loop through each row of the datatable 
{ 
StringBuilder errorStringBuilder = new StringBuilder(); //stores string error message because there would be more validations 
Record record = new Record() { 
Domain = row["Domain"].ToString(), 
Username = row["Username "].ToString(), 
Details = row["Details"].ToString(), 
}; 

if(most efficient way to determine if row has duplicates which returns bool) 
{ 
    //most efficient way to get the other rows that the current row duplicates 
    errorStringBuilder.Append("Duplicate with: "..)//append rows that it duplicates 

} 
if(errorStringBuilder.Length != 0) 
{ 
    record.ErrorMessage = sb.toString(); 
    record.IsValid = false; 
} 

은}

괜찮을 것 LINQ를 사용하여 목록

return new List().Add(
    new Record(){Row=1, Domain=x, Username=sam1, Details=1234, ErrorMessage=Duplicate row for r3, r6,IsValid=false} 
    new Record(){Row=2, Domain=x, Username=jack1, Details=4412, ErrorMessage=,IsValid=true} 
    new Record(){Row=3, Domain=x, Username=sam1, Details=1233, ErrorMessage=Duplicate row for r3, r6,IsValid=false} 
    new Record(){Row=4, Domain=y, Username=jack1, Details=4442, ErrorMessage=,IsValid=true} 
    new Record(){Row=5, Domain=z, Username=jason1, Details=5522, ErrorMessage=,IsValid=true} 
    new Record(){Row=6, Domain=x, Username=sam1, Details=8949, ErrorMessage=Duplicate row for r3, r6,IsValid=false}); 

를 반환했습니다. 나는 단지 가장 효율적인 방법을 원한다. 당신은 모든 행, 중복 및 고유 사람을 찾을 것입니다이 그룹에서

var usernameDomainGroups = excelDataTable.AsEnumerable() 
    .Select((r, index) => new { Row = row, RowNumber = index + 1}) 
    .GroupBy(x => new {UserName = x.Row.Field<string>("Username"), Domain = x.Row.Field<string>("Domain")}); 

:

답변

2

당신은 효율적인 방법 Enumerable.GroupBy를 사용할 수 있습니다. 루프를 사용하여 레코드를 처리하고 레코드 목록을 작성할 수 있습니다. 까다로운 부분은 중복 정보를 생성하는 것입니다.

foreach (var group in usernameDomainGroups) 
{ 
    bool isValid = !group.Skip(1).Any(); 
    if (isValid) 
     recordList.Add(new Record 
     { 
      Row = group.First().RowNumber, 
      Domain = group.Key.Domain, 
      Username = group.Key.UserName, 
      Details = group.First().Row.Field<string>("Details"), 
      IsValid = true, 
      ErrorMessage = null 
     }); 
    else 
    { 
     // tricky part, if you need further help ask 
     // start with group.Select(r => new Record .... 
     // then you can use recordList.AddRange(...) 
    } 
} 
+0

행 및 도메인별로 그룹화하는 것이 의미가 없기 때문에 (행이 고유 키임) 사용자 이름과 도메인별로 그룹화하는 것이 좋습니다. – Evk

+0

@Evk : whoops, edited :) –