代码优先一对一的关系

时间:2012-10-31 10:01:18

标签: entity-framework ef-code-first code-first one-to-one

我正在使用Code First编写一个模型,其中包含两个实体:'Action'和'Permission'。

每个Permission都指向一个Action。 没有两个权限可能指向相同的操作。 可能存在一个动作,而不是由权限指出。

操作不应该知道权限。

我的代码是:

public Action
{
  public Guid Id {get; set;}
  public string Name {get; set;}
}

public Permission
{
  public Guid Id {get; set;}
  public string Name {get; set;}

  public Action Action {get; set;}
}

另外,我使用Fluent API配置了权限:

modelBuilder.Entity<Permission>.HasRequired(p => p.Action).WithOptional()
            .WillCascadeOnDelete();

当我尝试删除Action时,出现以下错误:

  

“与处于已删除状态的实体添加关系是   不允许“。

我尝试先删除权限,然后删除操作。为此,我需要获取给定操作ID的权限,但我收到此错误:

var permission = (from p in context.Permissions.Include(p => p.Action)
                  where p.Action.Id == actionId
                  select p).Single();
  

“不支持索引属性”

我做错了什么?有没有更好的approch来模拟这个?

谢谢! 尼尔

1 个答案:

答案 0 :(得分:0)

三个建议,我没有尝试过第一个看看是否有效:

建议#1 将具有FK属性的外键添加到模型中,如:

public Permission
{
  public Guid Id {get; set;}
  public string Name {get; set;}

  [ForeignKey("Action")]
  public int ActionId {get; set;}
  public Action Action {get; set;}
}

然后尝试:

var permission = (from p in context.Permissions.Include(p => p.Action)
              where p.ActionId == actionId
              select p).Single();

建议#2可在此处找到:

EF 4.1: Difference between .WithMany() and .WithOptional() ?

建议#3

我们有类似的模型,但我们让双方都互相了解。您是否有理由不想在操作中包含权限导航属性?你可以这样做:

public Action
{
  public Guid Id {get; set;}
  public string Name {get; set;}

  // notice the FK is nullable 
  public int? PermissionId {get; set;}
  public Permission {get; set;}
}

以下是我们如何构建模型,每个Document与DocumentType具有1..1关系:

public class Document 
{ 

#region " Mutually exclusive document type relationships, necessary for setting up shared primary key in db "
public BindingAgreement BindingAgreement { get; set; }
public CeoLetter CeoLetter { get; set; }
public Email Email { get; set; }
....   
#endregion
//other code
}

Public class BindingAgreement 
{
  public Document {get;set;}
  // other code
}

Public class CeoLetter 
{
  public Document {get;set;}
  // other code
}

Public class Email 
{
  public Document {get;set;}
  // other code
}

然后在我的模型构建器中我这样做:

  //Binding Agreement
  modelBuilder.Entity<BindingAgreement>().HasRequired(c => c.Document);

  //Ceo Letter
  modelBuilder.Entity<CeoLetter>().HasRequired(c => c.Document);

  //Email
  modelBuilder.Entity<Email>().HasRequired(c => c.Document);

除此之外,我使用的是我的主键,但我不明白为什么这会是一个因素。

如果你可以拥有一个没有Permission的Action,我也不确定你需要删除级联。如果您无法获得没有权限的Action,则需要使用(Has / With)必需的流畅地图或通过以允许CF解释您的意图的方式明确构建您的代码来表明。

我稍后会尝试前两个建议,让你知道我的结果。