1

エンティティ フレームワークが「コード ファースト」と述べているように、ここではコードを最初に使用します...

public class BaseModel
{
    [Key]
    public Guid Id { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime DateChanged { get; set; }

    public BaseModel()
    {
        this.Id = Guid.NewGuid();
        this.DateCreated = DateTime.Now;
        this.DateChanged = DateTime.Now;
    }
}

public class Association: BaseModel
{
    public string Name { get; set; }
    public string Type { get; set; }

    public virtual List<Rule> Rules { get; set; }

    public Association()
        : base()
    {
    }
}

public class Rule: BaseModel
{
    [ForeignKey("Association")]
    public Guid AssociationId { get; set; }

    //[Required]
    public virtual Association Association { get; set; }

    //[Required]
    public string Name { get; set; }

    public string Expression { get; set; }

    public virtual List<Action> Actions { get; set; }

    public Rule()
        : base()
    {
    }
}

public class Action: BaseModel
{
    public string Name { get; set; }

    public string ActionType { get; set; }

    [ForeignKey("Rule")]
    public Guid RuleId { get; set; }

    public virtual Rule Rule { get; set; }

    public int Order { get; set; }

    public Action()
        : base()
    {
    }
}

これらは、最初にエンティティ フレームワーク コードを使用する 4 つのモデル クラスです。それぞれが基本クラスから継承するため、それらはすべて主キーとして Id Guid を持っています。

Association にはルールのリストがあります。(ルールには関連への FK があります) ルールにはアクションのリストがあります。(アクションにはルールへの FK があります)

やりたいことは、最上位のクラス=アソシエーションだけを変更して保存することです。たとえば、ルールを削除する場合、次のコードを機能させたいと思います。

 public ActionResult DeleteRule(Guid assId, Guid ruleId)
    {
        Association ass = this.DataContext.Associations.FirstOrDefault(a => a.Id == assId);
        ass.Rules.RemoveAll(r => r.Id == ruleId);

        this.DataContext.SaveChanges();

        return RedirectToAction("Index");
    }

context.savechanges で、次のエラーが表示されます。リレーションシップに変更が加えられると、関連する外部キー プロパティが null 値に設定されます。外部キーが null 値をサポートしていない場合は、新しい関係を定義するか、外部キー プロパティに別の非 null 値を割り当てるか、関連のないオブジェクトを削除する必要があります。

このエラーは、アクションを削除するときにも発生します。

最も上位の (関連付け) オブジェクトを変更し、この関連付けにのみ変更する方法はありますか? context.Rules.remove(...) または context.actions.remove(...) とは言いたくない

ソースは次のとおりです: http://server.thomasgielissen.be/files/mvctesting.zip VS2012 が必要です。すべての nuget パッケージは zip に含まれており、プロジェクトをビルドして実行できるはずです。

フィードバックをお寄せいただきありがとうございます。

グリーツ、トーマス

4

1 に答える 1

0

この問題を解決するには、ジャンクション テーブルを介してリレーションを保存する必要があります。このモデルでは、必要なものを達成できるとは思いません。

ただし、エンティティ間にジャンクション テーブル (またはエンティティ) を配置すると、子オブジェクトを簡単に削除して親オブジェクトを更新できます。

たとえば、 と の間にジャンクション エンティティを配置しAssociationますRule

public class AssociationRule: BaseModel
{
    public Guid AssociationId { get; set; }
    public Guid RuleId { get; set; }

    [ForeignKey("AssociationId")]
    public virtual Association Association { get; set; }
    [ForeignKey("RuleId")]
    public virtual Rule Rule { get; set; }        

    public Association()
        : base()
    {
    }
}

これで、関連付けからルールを簡単に削除できます。

public ActionResult DeleteRule(Guid assId, Guid ruleId)
{
    AssociationRule assr = this.DataContext
        .AssociationRuless
        .FirstOrDefault(ar => ar.AssociationId == assId && ar.RuleId == ruleId);

    this.DataContext.AssociationRules.Remove(assr);
    this.DataContext.SaveChanges();

    return RedirectToAction("Index");
}
于 2013-08-03T07:59:32.273 に答える