1

と呼ばれるエンティティがCostあります。これには、次の必須プロパティがあります。CostType

このCostクラスにはGetNew()、Costのすべてのデフォルトを設定するメソッドがあります。

public static GetNew()
{
    Cost cost = new Cost ();
    foo.CostType = Lists.CostTypes.FirstOrDefault();
    // Other Default Values

    return foo;
}

これLists.CostTypesは、起動時にEFから取得され、ComboBoxesで使用される静的リストです。

最初にメソッドでCostTypeを設定した後、コード内でCostTypeを設定する際に問題が発生しますGetNew()

たとえば、次のコードはExcelファイルを読み取り、Excelファイルの列に基づいてデフォルトのタイプを設定します。一致するものが見つからない場合はnullを設定します。

Cost cost = Cost.GetNew();
cost.CostType = Lists.CostTypes.FirstOrDefault(t => t.Name == row[0].ToString());

私の問題は、保存操作中に次のエラーが発生することです。

操作が失敗しました:1つ以上の外部キープロパティがnull許容でないため、関係を変更できませんでした。リレーションシップに変更が加えられると、関連する外部キープロパティがnull値に設定されます。外部キーがnull値をサポートしていない場合は、新しい関係を定義するか、外部キープロパティに別の非null値を割り当てるか、関連のないオブジェクトを削除する必要があります。

私の追加操作は次のようになります。

public static void AddObject(EntityObject obj, string entitySetName)
{
    context.AddObject(entitySetName, obj);
    context.SaveChanges();
}
  • Excelファイルを読み取るときにコストを手動で設定するコード行を削除すると、保存は正常に機能します。
  • Lists.Costs [2]を読み取るようにコード行を変更すると、問題なく保存されます。
  • デフォルトを設定しているコード行を削除するとGetNew()、CostTypesのPKルールに違反しているというエラーが表示されます。これは、CostTypeを挿入しようとしていることを意味します。
  • Typeを表示しているComboBoxを別のものに変更しても、同じエラーが発生します。
  • Excelファイルからコストを読み込んだ後、タイプを変更して保存しようとすると、通常の追加/編集フォームで同じエラーがスローされます。Excelファイルを読み込まない場合は、正常に機能します。

私はまだEntityFrameworkを学んでいますが、これまでのところ、使用するのはフラストレーションと頭痛の種に過ぎません。誰かが私の問題が何であるか、そして私がそれをどのように修正できるか知っていますか?

編集

これがSlaumaから要求された情報です。私はそれをシンプルに保ち、無関係なオブジェクトを除外しています

  • CostsあるテーブルにありCostTypes、別のテーブルにあります。データベースでは、Costs.TypeId列をnullにすることはできず、への外部キーCostTypesです。両方のテーブルのIdフィールドは自動生成されます。

  • 私のEFモデルは、2つのデータベーステーブルが追加された一般的なモデルです。私が行った唯一の変更は、一部のフィールドの名前を変更し、CostTypes.CostsNavigationプロパティを削除することでした。

  • インポートされるExcelファイルは、ほとんどのコストを一致するものにマップしますがCostType.Name、Excelファイルの文字列がに一致しない可能性があるCostTypeため、Lists.CostTypes.FirstOrDefault(t => t.Name == row[0].ToString()) can assign aNULL value to theCost.Type property. That doesn't seem to be a problem though, because the form still comes up with the list of costs and their default selected items. Item's with aNULL CostType do not have an item selected in the CostTypeComboBox`を実行し、保存する前に修正する必要がある検証エラーをトリガーします。

CostTypeリストをロードするコードは次のとおりです。

public static List<T> GetList<T>(string sortProperty)
    where T : EntityObject
{
    using (var context = new TContext())
    {
        return ApplyOrder<T>(context.CreateObjectSet<T>(), sortProperty, "OrderBy").ToList();
    }
}

ApplyOrderコードはここにあります

GetListメソッドはから呼び出されます

public static class Lists
{
    public static List<CostType> CostTypes { get; private set; }

    static Lists()
    {
        CostTypes = DAL<CostEntities>.GetList<CostType>("Name");
    }
}
4

2 に答える 2

2

私はそれを理解しました....それはいくつかの異なるものの混合物でした

新しいものを作成しCostて設定するTypeと、共有データコンテキストにコストが追加されていました。そのコストが保存するコストのリストに含まれていなかった場合、検証エラーに失敗した場合、またはユーザーが[インポート]ダイアログをキャンセルした場合、またはに電話したことがなくても、コストはに残っていましcontext.ObjectStateManager._addedObjectsた。節約できないコストを請求し始めたことに気づいたら、最初に発生したエラーが解消されました。AddObjectAttachObjectDeleteObject

私が得た2番目のエラー(重複PK)は、新しいコストをループして、それぞれに呼び出しAddObjectを行っていたためSaveChangesです。Cost.Type添付ファイルに設定するCostTypeと、コンテキストにコストが自動的に追加されるため、最初のコストを節約するには、実際にはすべての新しいコストをデータベースに追加し、2番目のコストはEFが既存のオブジェクトと見なしたものを呼び出そうAddObjectとしました。SaveChanges

于 2011-08-23T19:31:10.277 に答える
1

これは実際には満足のいく答えではありませんが、質問と質問へのコメントの情報に基づいた推測と未解決の質問の組み合わせです。

  • まず第一に:あなたのリストLists.CostTypesには明らかに、後で新しいオブジェクトを追加および保存するコンテキストから切り離さusingれたエンティティが含まれています。ブロックがあるため:別のコンテキストでエンティティをusing (var context = new TContext())取得しています。CostType

  • これらのCostTypeエンティティがデータベースにすでに存在することをEFに通知するには、変更を保存する2番目のコンテキスト()にエンティティをアタッチcontext.CostTypes.Attach(costType)する必要があります(または、リストを取得するメソッドで同じコンテキストを使用します)。私はあなたがこれをしていることをあなたのコードで見ていません。(CostTypeナビゲーション参照プロパティであり、外部キープロパティではありませんか?)

  • 一方、CostTypeエンティティがアタッチされていない場合は、データベースに重複したCostTypesを取得する必要があります。これは、EFが常にデタッチされたオブジェクトグラフ全体を配置するAddObjectため、エンティティを呼び出すときにEFがそれらを新しいオブジェクト(DBに挿入するため)と見なすためです。CostエンティティをAdded状態にします。作業例のDBで重複したCostTypeを取得しますか?そうでない場合は、コードスニペットに重要なものがありません。

  • CostType最後の段落では、あなたが言ったように、のキーがDBで自動生成されることを前提としています。そうでない場合は、エンティティが重複する代わりにPK制約違反が発生します。

  • CostTypeとのキーCostが本当に自動生成されたIDである場合、あなたが言及したPK違反はどこから来るのか疑問に思います。挿入するたびに、新しい一意の主キーが作成されます。PKビオラトンが発生することはありません。例外メッセージを詳しく表示できますか?

  • Cost保存するすべてのエンティティが本当にnull以外のプロパティを持っていることを確認しましたかCostType(ユーザーがすべての検証エラーを修正した後)?Cost少なくとも1つのオブジェクトCostTypeがである場合を除いて、「Relationship-could-not-be-changed-exception」が発生する理由は、コード内に他に考えられませんnull

于 2011-08-23T19:14:24.397 に答える