2011-02-25 4 views
0

안녕하세요, 저는 ui 레이어로 그룹 데이터를 반환하고 싶습니다.내 그룹화를 단순화

여기 groupby "GenerationDate"를 단순화하고 목록 <>의 데이터를 UI gridview로 돌려 보내려고합니다. 나는 forloop을해야하므로 매우 성가신 것을 느낍니다. 또한 UI 레이어에서 나는이 간단한 groupby를 위해 forloop을 또 하나해야한다. 그것을 단순화하는 데 도움이 될 수 있습니까?

public List<SalaryTracker> GetSalaryTrackerOrderByGenerationDate(int tutorId) 
{ 
    List<SalaryTracker> salary = new List<SalaryTracker>(); 
    using (leDataContext db = new leDataContext()) 
    { 
     try 
     { 
      var r = 
       from s in db.SalaryTrackers 
       where s.StaffId == 2 && s.PaymentDate == null 
       group s by s.GenerationDate into g 
       where g.Count() > 0 
       select new 
       { 
        date = g.Key, totalSalary = g.Sum(p => p.SalaryAmount) 
       }; 

      foreach (var rr in r) 
      { 
       SalaryTracker m = new SalaryTracker(); 
       m.GenerationDate = rr.date; 
       m.SalaryAmount = rr.totalSalary; 
       salary.Add(m); 
      } 

      return salary; 
     } 
     catch (Exception ex) 
     { 
      Logger.Error(typeof(SalaryTracker), ex.ToString()); 
      throw; 
     }      
    } 
} 

--------------- 내가 이렇게

totalCommissionsGroup = salary.GetSalaryTrackerOrderByGenerationDate(tutor.Id); 

IList<SalaryTracker> rr = (
    totalCommissionsGroup.GroupBy(x => x.GenerationDate) 
    .Select(g => new SalaryTracker 
    { 
     MonthId = g.Key.Month, 
     MonthToPay = common.GetMonthName(Convert.ToInt16(g.Key), true), 
     SalaryAmount = g.Sum(x => x.SalaryAmount) 
    })).ToList<SalaryTracker>(); 

gvSalaryPayment.DataSource = rr;   

GUI

내가 문자열

답변

2
public List<SalaryTracker> GetSalaryTrackerOrderByGenerationDate(int tutorId) 
{ 
    using (var db = new leDataContext()) 
    { 
     try 
     { 
      return (
       from s in db.SalaryTrackers 
       where s.StaffId == 2 && s.PaymentDate == null 
       group s by s.GenerationDate into g 
       select new 
       { 
        MonthId = g.Key.Month, 
        // I don't know what "common" is in your UI code, 
        // I am just using GetMonthName here 
        MonthToPay = GetMonthName(Convert.ToInt16(g.Key), true), 
        SalaryAmount = g.Sum(p => p.SalaryAmount) 
       }) 
       .AsEnumerable() 
       .Select(x => new SalaryTracker 
       { 
        MonthId = x.MonthId, 
        MonthToPay = x.MonthToPay, 
        SalaryAmount = x.SalaryAmount 
       }) 
       .ToList(); 
     } 
     catch (Exception ex) 
     { 
      Logger.Error(typeof(SalaryTracker), ex.ToString()); 
      throw; 
     } 
    } 
} 
+0

안녕하세요, 답장을 보내 주셔서 감사합니다. 이 오류가 있습니다. "{"쿼리에서 엔티티 유형 'le.DataModel.SalaryTracker'의 명시 적 생성이 허용되지 않습니다. "}". 나는 이것이 MonthToPay 속성 때문이라고 생각합니다. public string MonthToPay {get; 세트; } salaryTracker 클래스에 추가 한 것은 무엇입니까? – VeecoTech

+0

SalaryTracker 클래스를 게시 할 수 있습니까? linq-to-sql을 사용하고 있습니까? –

+0

예 SQL에 linq을 사용하고 있습니다. 클래스 내 속성 '이다 공공 부분 클래스 SalaryTracker { 공공 INT MonthId {얻을; 세트; } public string MonthToPay {get; 세트; } 공개 DateTime lastPaymentDate {get; 세트; } 공통 공통 = 새 공통(); ' 그리고 정확하게 당신이 작성한 함수로 – VeecoTech

0

I에 MonthToPay를 얻을 수 있도록 Mahesh Velaga (+1)에 대한 리팩토링에 동의하고 그 어플리케이션의 해당 레벨에서의 로깅 오류가 비정상적이라고 덧붙입니다. 특히 어떤 식 으로든 예외를 제하기로 결정한 경우. 따라서 오류 로깅을 사용하여 전체 try catch을 제거하고 응용 프로그램의 루트에만 로그하는 것이 좋습니다 (아직 수행하지 않은 경우). 이렇게하면 코드를 훨씬 더 깔끔하게 정리할 수 있습니다.

이렇게하면 비즈니스 논리 이외의 다른 방법으로 읽을 수있는 좋은 방법이 남았음을 알 수 있습니다. 우리는이 데이터 모델 층에서 '을 캐치 시도'넣어하지 않는 경우

UPDATE

하지만, 어떻게 주요 발신자는 오류를 잡을 것인가? 나는 년 동안이 패턴을 사용 해왔다. 내가 틀렸다면 나를 바로 잡아주세요. 이 link에 을 입력하십시오.

  • 로깅, 잡기와 서비스에 rethrowing :

당신이 당신의 질문을 할 또는 귀하가 제공하는 referenced article에 도시 된 바와 같이 수행되는 방식을 잡기 때문에 여러 가지 이유로, 거의 항상 하위 최적 계층은 불행한 일입니다. 왜냐하면 로깅 시스템에서이 오류의 이중 항목으로 끝나기 때문입니다. 어쨌든 응용 프로그램의 최상위 계층에 로그온해야하기 때문입니다. 그렇지 않으면 서비스에서 발생하지 않은 로깅 오류가 누락 될 수 있기 때문입니다 층. 오류를 무시하면 클라이언트는 거의 오류가 발생하지 않아야하므로 오류를 무시합니다 (으로 다시 보냄).

  • referenced article에 표시된 것처럼 프리젠 테이션 레이어를 잡아내는 것은 불행한 일입니다.이 방법으로 오류를 기록하지 않아도되지만 더 중요한 것은 사용자에게 기술적이고 모호한 오류 메시지 (아마도 외국어) 그들은 이해하지 못하고 그것들을 좌절시킬 것입니다. 더 나쁜 것은 해커가 공개적으로 노출 된 웹 응용 프로그램의 경우 응용 프로그램을 공격 할 때 표면 아래에서 진행되는 것을 볼 수있는 정보 유출로 이어질 수 있습니다.
  • 이것은 사용자에게 오류 정보를 표시 할 수는 없지만 사용자에게 오류 정보를 제공하기 위해 명시 적으로 throw 한 예외에 대해서만 수행한다는 것을 의미하지는 않습니다.예를 들어 :이 예에서

    try 
    { 
        // Call into service layer 
    } 
    catch (BusinessLayerException ex) 
    { 
        this.ValidationSummary1.Add(new CustomValidator 
        { 
         ErrorMessage = ex.Message, IsValid = false 
        }); 
    } 
    

    BusinessLayerException 응용 프로그램에 의해 사용되는 경우 가능성이 지역화 된 오류 메시지와 함께 사용자 (대한 이해할 오류 메시지가 포함 된 비즈니스 계층에서 발생되는 특수 예외입니다 여러 언어 사용자).

    다른 모든 예외를 들어, 대부분의 시간을 당신이 잘못된 방법 심각한 오류가 어떤 정보를 예외에 포함 된 내용을 아무 생각이 없기 때문에, 오류 메시지가 정확한 사용자에게 보여주고 싶지 않아요. 가장 좋은 방법은 프리젠 테이션 레이어에서 최대한 적은 오류 처리 로직을 사용하고 응용 프로그램의 최상위 레이어의 한 위치에서이를 처리하는 것입니다. 이 경우 오류 페이지가 사용자에게 표시되는지 확인하고 오류가 로깅 시스템에 기록되는지 확인하십시오.

    당신은 configure ASP.NET 오류의 경우 사용자 지정 오류 페이지를 표시 할 수 있습니다.

    <customErrors mode="RemoteOnly" 
        defaultRedirect="~/ErrorPage.htm"> 
    </customErrors> 
    

    ErrorPage.htm에 유래에서 여기 오류 페이지 "그것은 우리의 잘못"일반 같은 일반적인 정보를 표시 할 수 있습니다 예를 들면 다음과 같습니다이다. 아마도 밤에 전화 할 수 있도록 지원 전화 번호, 집 전화 번호 등

    Application_Error 메서드를 global.asax에 구현하면 응용 프로그램 로그의 한 곳에서 처리되지 않은 예외를 처리 할 수 ​​있습니다.

    void Application_Error(object sender, EventArgs e) 
    { 
        Exception ex = Server.GetLastError(); 
    
        // Log the exception here. 
    } 
    

    당신이 알에게 같은 스택 추적, 오류 메시지, 예외 유형 및 발생할 수있는 모든 내부 예외로 당신이 필요로하는 오류에 대한 정보를 기록해야합니다.

    이 정보가 도움이되기를 바랍니다.

    +0

    안녕하세요. Steven, UI 수준에서 중복성을 제거하기 위해 좀 더 리팩토링했습니다. upvote 주셔서 감사합니다 :) –

    +0

    @ 마헤 : 좋은 찾고 ;-) – Steven

    +0

    안녕하세요 Mahesh, 답장을 보내 주셔서 감사합니다. 그러나 데이터 모델 계층에 'try catch'를 넣지 않으면 주 호출자가 오류를 어떻게 catch합니까? 나는이 패턴을 수년간 사용 해왔다. 만약 내가 틀렸다면 나를 바로 잡아라. [link] (http://www.codeproject.com/KB/architecture/three_tier_architecture.aspx)를 참조하십시오. – VeecoTech