2013-04-13 4 views
1

몇 가지 문제점이 있습니다. 내가 EntityFramework 5를 사용계단식 나무 (부모/자식) 데이터 추가/업데이트

CREATE TABLE [EvaluationProcess].[CriteriaHeader](
    [CriteriaHeader_No] [uniqueidentifier] NOT NULL, 
    [CriteriaHeader_Type] [int] NOT NULL, 
    [CriteriaHeader_Name] [nvarchar](128) NOT NULL, 
    [CriteriaHeader_Description] [nvarchar](256) NULL, 
    [CriteriaHeader_MaxScore] [int] NOT NULL, 
    [CriteriaHeader_MinScore] [int] NOT NULL, 
    [CriteriaHeader_ScoreStep] [int] NOT NULL, 
    [CriteriaHeader_IsCountedResult] [bit] NOT NULL, 
    [CriteriaHeader_IsBlocked] [bit] NOT NULL, 
    [OwnedOrganisationID] [uniqueidentifier] NULL, 
    [ModifyUser] [uniqueidentifier] NULL, 
    [ModifyDate] [datetime] NULL, 
    [TimeStamp] [timestamp] NULL, 
CONSTRAINT [PK_Criteria] PRIMARY KEY CLUSTERED 
(
    [CriteriaHeader_No] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

ALTER TABLE [EvaluationProcess].[CriteriaHeader] ADD CONSTRAINT [DF_Criteria_Criteria_No] DEFAULT (newsequentialid()) FOR [CriteriaHeader_No] 
GO 

ALTER TABLE [EvaluationProcess].[CriteriaHeader] ADD CONSTRAINT [DF_Criteria_Criteria_Type] DEFAULT ((0)) FOR [CriteriaHeader_Type] 
GO 

ALTER TABLE [EvaluationProcess].[CriteriaHeader] ADD CONSTRAINT [DF_Criteria_Criteria_MaxScore_1] DEFAULT ((5)) FOR [CriteriaHeader_MaxScore] 
GO 

ALTER TABLE [EvaluationProcess].[CriteriaHeader] ADD CONSTRAINT [DF_Criteria_Criteria_MinScore_1] DEFAULT ((0)) FOR [CriteriaHeader_MinScore] 
GO 

ALTER TABLE [EvaluationProcess].[CriteriaHeader] ADD CONSTRAINT [DF_Criteria_Criteria_ScoreStep_1] DEFAULT ((1)) FOR [CriteriaHeader_ScoreStep] 
GO 

ALTER TABLE [EvaluationProcess].[CriteriaHeader] ADD CONSTRAINT [DF_Criteria_Criteria_IsCountedResult] DEFAULT ((0)) FOR [CriteriaHeader_IsCountedResult] 
GO 

ALTER TABLE [EvaluationProcess].[CriteriaHeader] ADD CONSTRAINT [DF_Criteria_Criteria_IsBlocked] DEFAULT ((0)) FOR [CriteriaHeader_IsBlocked] 
GO 

ALTER TABLE [EvaluationProcess].[CriteriaHeader] ADD CONSTRAINT [DF_Criteria_ModifyDate] DEFAULT (getdate()) FOR [ModifyDate] 
GO 

CREATE TABLE [EvaluationProcess].[CriteriaLine](
    [CriteriaLine_No] [uniqueidentifier] NOT NULL, 
    [CriteriaLine_ParentID] [uniqueidentifier] NULL, 
    [CriteriaLine_CriteriaHeaderID] [uniqueidentifier] NULL, 
    [CriteriaLine_Text] [nvarchar](128) NOT NULL, 
    [CriteriaLine_Description] [nvarchar](512) NULL, 
    [OwnedOrganisationID] [uniqueidentifier] NULL, 
    [ModifyUser] [uniqueidentifier] NULL, 
    [ModifyDate] [datetime] NULL, 
    [TimeStamp] [timestamp] NULL, 
CONSTRAINT [PK_CriteriaList] PRIMARY KEY CLUSTERED 
(
    [CriteriaLine_No] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

ALTER TABLE [EvaluationProcess].[CriteriaLine] ADD CONSTRAINT [DF_CriteriaList_CriteriaList_No] DEFAULT (newsequentialid()) FOR [CriteriaLine_No] 
GO 

ALTER TABLE [EvaluationProcess].[CriteriaLine] ADD CONSTRAINT [DF_CriteriaList_ModifyDate] DEFAULT (getdate()) FOR [ModifyDate] 
GO 

ALTER TABLE [EvaluationProcess].[CriteriaLine] WITH CHECK ADD CONSTRAINT [FK_CriteriaLine_CriteriaLine] FOREIGN KEY([CriteriaLine_CriteriaHeaderID]) 
REFERENCES [EvaluationProcess].[CriteriaHeader] ([CriteriaHeader_No]) 
ON UPDATE CASCADE 
ON DELETE CASCADE 
GO 

ALTER TABLE [EvaluationProcess].[CriteriaLine] CHECK CONSTRAINT [FK_CriteriaLine_CriteriaLine] 
GO 

ALTER TABLE [EvaluationProcess].[CriteriaLine] WITH CHECK ADD CONSTRAINT [FK_CriteriaLine_CriteriaLine1] FOREIGN KEY([CriteriaLine_ParentID]) 
REFERENCES [EvaluationProcess].[CriteriaLine] ([CriteriaLine_No]) 
GO 

ALTER TABLE [EvaluationProcess].[CriteriaLine] CHECK CONSTRAINT [FK_CriteriaLine_CriteriaLine1] 
GO 

이것은 추가/업데이트 기능

public override bool InsertOrUpdate(object[] _BaseEntityClasses, string _RoleName, 
            System.Nullable<Guid> _LoginUserID, 
             System.Nullable<System.Guid> _OrganisationID, bool? IsModified = null) 
{ 
    using (Evaluation_SystemConection EvaluationDBContext = new Evaluation_SystemConection()) 
    { 
     try 
     { 
      EvaluationDBContext.Configuration.AutoDetectChangesEnabled = false; 

      IEnumerable<CriteriaHeader> _BaseEntityClassesList = _BaseEntityClasses.Cast<CriteriaHeader>(); 

      foreach (var OneItem in _BaseEntityClassesList) 
      { 
       if (OneItem.CriteriaLines != null) 
       { 
        foreach (var OneLine in OneItem.CriteriaLines) 
        { 
         if (OneLine.CriteriaLine_No == Guid.Empty) 
          OneLine.CriteriaLine_CriteriaHeaderID = OneItem.CriteriaHeader_No; 

         EvaluationDBContext.CriteriaLines.Attach(OneLine); 


         EvaluationDBContext.Entry(OneLine).State = OneLine.CriteriaLine_No == Guid.Empty ? EntityState.Added : EntityState.Modified; 

        } 

       } 

       EvaluationDBContext.CriteriaHeaders.Add(OneItem); 

       EvaluationDBContext.Entry(OneItem).State = OneItem.CriteriaHeader_No == Guid.Empty ? EntityState.Added : EntityState.Modified; 

       if (EvaluationDBContext.SaveChanges() <= 0) 
        return false; 
      } 

      return true; 
     } 
     catch (Exception Ex) 
     { 
      ErrorMessage.Add(""); 

      ErrorMessage.Add((Ex.InnerException != null) ? Ex.InnerException.Message : Ex.Message); 

      return false; 
     } 
     finally 
     { 
      EvaluationDBContext.Configuration.AutoDetectChangesEnabled = true; 
     } 
    } 

} 

그리고 생성 POCO 클래스

데이터 삽입하지 않았다

public partial class CriteriaHeader 
{ 
    public CriteriaHeader() 
    { 
     this.CriteriaLines = new HashSet<CriteriaLine>(); 
    } 

    public System.Guid CriteriaHeader_No { get; set; } 
    public int CriteriaHeader_Type { get; set; } 
    public string CriteriaHeader_Name { get; set; } 
    public string CriteriaHeader_Description { get; set; } 
    public int CriteriaHeader_MaxScore { get; set; } 
    public int CriteriaHeader_MinScore { get; set; } 
    public int CriteriaHeader_ScoreStep { get; set; } 
    public bool CriteriaHeader_IsCountedResult { get; set; } 
    public bool CriteriaHeader_IsBlocked { get; set; } 
    public Nullable<System.Guid> OwnedOrganisationID { get; set; } 
    public Nullable<System.Guid> ModifyUser { get; set; } 
    public Nullable<System.DateTime> ModifyDate { get; set; } 
    public byte[] TimeStamp { get; set; } 

    public virtual ICollection<CriteriaLine> CriteriaLines { get; set; } 
} 

public partial class CriteriaLine 
{ 
    public CriteriaLine() 
    { 
     this.CriteriaLine1 = new HashSet<CriteriaLine>(); 
    } 

    public System.Guid CriteriaLine_No { get; set; } 
    public Nullable<System.Guid> CriteriaLine_ParentID { get; set; } 
    public Nullable<System.Guid> CriteriaLine_CriteriaHeaderID { get; set; } 
    public string CriteriaLine_Text { get; set; } 
    public string CriteriaLine_Description { get; set; } 
    public Nullable<System.Guid> OwnedOrganisationID { get; set; } 
    public Nullable<System.Guid> ModifyUser { get; set; } 
    public Nullable<System.DateTime> ModifyDate { get; set; } 
    public byte[] TimeStamp { get; set; } 

    public virtual CriteriaHeader CriteriaHeader { get; set; } 
    public virtual ICollection<CriteriaLine> CriteriaLine1 { get; set; } 
    public virtual CriteriaLine CriteriaLine2 { get; set; } 
} 
또는 업데이트는이 데이터베이스 구조 CriteriaList에서 1 단계 이상.

내가 뭘 잘못 했니?

답변

0

먼저 항상 AutoDetectChangesEnabled을 변경하지 마십시오. 이것을 사용할 때 실제로 무엇을하는지 (그리고하지 않는지) 철저히 이해해야합니다. 먼저해야 할 일은 AutoDetectChangesEnabled을 만지지 않는 것입니다. 그것은 당신의 방법이 그것 없이도 작동 할 수있는 것처럼 보입니다. 그렇지 않다면 어떤 일이 발생했는지 알려주므로 우리는 그 문제를 해결하려고 노력할 수 있습니다. (나는 당신이 AutoDetectChangesEnabled을 변경함으로써 예방하려고 시도한 몇 가지 이슈가 발생할 것이라고 생각합니다).

엔티티 프레임 워크 자체의 AddOrUpdate method을 사용할 수 있습니다. 당신이

EvaluationDBContext.CriteriaHeaders.Add(OneItem); 
EvaluationDBContext.Entry(OneItem).State = OneItem.CriteriaHeader_No == Guid.Empty ? EntityState.Added : EntityState.Modified; 

이 어디 그래서 당신은

EvaluationDBContext.CriteriaHeaders.AddOrUpdate(OneItem); 

(마찬가지로 CriteriaLines 포함) 할 수있다.

그러나 삽입 또는 업데이트해야하는지 여부를 확인하려면 각 레코드에 대해 데이터베이스 왕복 시간이 필요합니다.

코드에 더 많은 문제가 있습니다.

  • 명명 규칙 (_BaseEntityClasses 같은 협약이
  • 당신은 입력 매개 변수로 object[]을 사용해서는 안 baseEntityClasses이지만, 제네릭을 사용합니다.. InsertOrUpdate<T>(IEnumerable<T> baseEntityClasses, ...
  • 당신은 인 일부 외부 ErrorMessage 목록을 갖고있는 것 같다 프로그램의 상태를 유지하는 방법입니다. 귀하의 방법에는 부작용이 있습니다. ErrorMessage이 영향을받는 장소와 언제 삭제해야하는지 알려주기가 어려울 수도 있습니다.
  • 정말 예외 처리가 아닙니다. 그들과 한 적절한 곳에서 그들을 줍시다.
  • 부울을 반환하지 않아야합니다. 특히 false을 반환하면 의미가 없습니다. 예를 들어 영향을받은 행 수를 반환 할 수 있습니다. 예외 재발생과 함께 소비자는 불리언 값보다 훨씬 더 많은 정보를 얻을 수 있습니다.
+0

감사의 답변 AutoDetectChangesEnabled = false. 성능 향상을 위해 사용합니다. 사실입니까? – PaataPP

+0

물론, 변경 추적기의 사용량이 적기 때문에 성능이 약간 향상되지만 잘 알고 있어야하는 부작용이 있습니다. 성능이 허용 가능하지 않고 성능을 향상시킬 수있는 다른 방법이없는 경우에만 사용하십시오. –