views:

127

answers:

1

I have a relational model with an associative table. But in addition to the related keys, this table also has a flag. I would like to define two associations: one where the flag is true and another where it is false. The EF designer can add a condition to an entity, but not to an association.

The associative table looks like this:

UserPrivilege
-------------
UserId int (FK1)
PrivilegeId int (FK2)
IsGranted bit

I would like to create two associations between the User entity and the Privilege entity: PrivilegesGranted and PrivilegesDenied.

+1  A: 

You can't do this directly through the designer.

But this is possible in the XML using DefiningQuery and Create and Delete sprocs. See this old post on my blog for more: Associations with Payloads.

The only thing that is a bit interesting is I assume the PK is just UserId and PrivilegeId, which means a user can't be granted and denied for a particular privilege at the same time.

So if you write code like this:

Privilege p = user.Granted.First();
user.Granted.Remove(p);
user.Denied.Add(p);
ctx.SaveChanges();

Update ordering is important. because you are using a DefiningQuery for both associations, the EF doesn't know they are related, and that it needs to do the delete before it can do the update.

So you might end up with PK violations.

A way to address this issue is in the Insert and Delete sprocs for each association, you can essentially make them change the current row for the User and Privilege pair, if it exists update it with the correct IsGranted value, if not create it, i.e. make it an upsert.

Let me know how you go here

Alex

Alex James