0

I am writing a model, using Code First, with two entities: 'Action' and 'Permission'.

Each Permission points to exactly one Action. No two Permissions may point to the same Action. An Action may exist without being pointed to by a Permission.

Actions should not be aware of Permissions.

My code is:

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;}
}

Also, I configured Permission using the Fluent API:

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

When I try to delete an Action, I get the following error:

"Adding a relationship with an entity which is in the Deleted state is not allowed".

I tried deleting the Permission first, and then the Action. For that, i needed to fetch the Permission given the Action ID, but i get this error:

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

"Indexed properties are not supported"

What am I doing wrong? Is there a better approch to model this?

Thanks! Nir

ni6go
  • 11
  • 3

1 Answers1

0

Three suggestions, I haven't tried the first one to see if it works:

Suggestion #1 Add a foreign key with the FK attribute to the model like:

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

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

Then try:

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

Suggestion #2 may be found here:

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

Suggestion #3

We have a similar model, but we make both sides aware of each other. Is there a good reason why you don't want to include a Permission navigation property in Action? You could do something like:

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;}
}

Here is how we structure our models, each Document has a 1..1 relationship with a DocumentType:

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
}

Then in my model builder I do this:

  //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);

Other than that, I am using ints for my primary key, but I don't see why that would be a factor.

I'm also not sure you need to have the deletes cascade if you can have an Action w/o a Permission. If you can't have an Action w/o a permission, you need to indicate that with the (Has/With)Required fluent map or by explicitly structuring your code in a manner that allows CF to interpret your intent.

I'll try the first two suggestions later and let you know my results.

Community
  • 1
  • 1