2013-07-31 141 views
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() 
    { 
    } 
} 

因此,这些都是我的四个模型类,使用实体框架代码第一。 每个都从基类继承,所以它们都有一个Id Guid作为主键。

一个关联有一个规则列表。 (规则具有FK给协会) 规则与动作列表一样。 (动作有FK来规则)

我想要做的只是改变并保存最向上的class = Association。 例如删除规则时,我想这个代码工作:

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: “操作失败:关系不能被改变,因为一个或更多的外键属性是不可空的。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性指定另一个非空值,或者必须删除不相关的对象。

删除操作时也会发生此错误。

有没有办法改变最上层(关联)对象,只有改变这个关联的东西。 我不想说context.Rules.remove(...)或context.actions.remove(...)

这里的源:http://server.thomasgielissen.be/files/mvctesting.zip 你需要VS2012,所有的Nu​​Get包包含在ZIP和你应该能够建立并运行项目。

在此先感谢您的反馈!

格尔茨, 托马斯

+0

您需要重新格式化这个问题。简化您的问题描述并在帖子中包含最少的相关代码。就目前而言,你很难获得帮助。 – Michal

+0

问题已更新!,希望我现在可以获得帮助:) –

回答

0

我要解决这个问题,您应该存储通过交接表的关系。我不认为你可以用这个模型达到你所需要的。

但是,如果您在实体之间放置联结表(或实体),则可以轻松地删除子对象并更新父对象。

例如,把一个结实体AssociationRule之间:

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"); 
} 
+0

我明白你要去哪里了,但这是什么意思,只是说 Rule rule = this.DataContext.Rules.FirstOrDefault(r => r.RuleId) this.DataContext.Remove(规则) 这也适用。 问题是我想只更新“所有父”=关联 所以 关联ass = this.DataContext.Associations.FirstOrDefault(a => a.Id == assId); ass.Rules.RemoveAll(r => r.Id == ruleId); this.DataContext.SaveChanges(); –

+0

@ThomasGielissen - 不,那不行。因为'Rule'本身就是'Action'的父项。如果动作表中的规则的外键不可空,则无法对某些规则执行删除。另一方面,通过删除您的方法中的规则,您将失去Rule实体!但在我的方法中,你只是打破了“协会”和规则之间的关系,没有任何其他问题或副作用。 – AminSaghi