1

問題があります。これはデータベース構造です:

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

私はEntityFramework 5を使用しています。これは追加/更新機能です

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

私は何を間違えましたか?

4

1 に答える 1

0

まず、常に変更を避けるようにしてくださいAutoDetectChangesEnabled。これを使用するときは、それが何をするか (およびしないか) を完全に理解する必要があります。ですので、まずは触らないことAutoDetectChangesEnabledです。あなたの方法はそれがなくても機能するようです。そうでない場合は、対処できるように、何が起こったのかをお気軽にお知らせください。( を変更して防止しようとしたいくつかの問題が発生すると思われますAutoDetectChangesEnabled)。

エンティティ フレームワーク独自のAddOrUpdate メソッドの使用を検討できます。だからあなたが持っている場所

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

あなたができる

EvaluationDBContext.CriteriaHeaders.AddOrUpdate(OneItem);

(同様にCriteriaLines)。

ただし、レコードを挿入または更新する必要があるかどうかを確認するには、レコードごとにデータベースへのラウンドトリップが必要です。

コードにはさらに問題があります。

  • 命名規則 ( など_BaseEntityClasses、規則はbaseEntityClasses.
  • 入力パラメーターとして使用するのではなくobject[]、ジェネリックを使用する必要があります: InsertOrUpdate<T>(IEnumerable<T> baseEntityClasses, ...
  • ErrorMessageステートフルなプログラミング方法である外部リストがあるようです。つまり、あなたの方法には副作用があります。ErrorMessageどこが影響を受けており、いつクリアまたは報告する必要があるかを判断するのは難しい場合があります。
  • あなたはどんな例外も飲み込みます。それは本当の例外処理ではありません。それらを再スローして、適切な場所で処理してください。
  • ブール値を返すだけではありません。特に返すfalseときは無意味です。たとえば、影響を受ける行の数を返すことができます。例外を再スローすることで、消費者はメソッドから単なるブール値よりもはるかに多くの情報を受け取ります。
于 2013-04-14T09:50:27.550 に答える