0

So I have an entity EmployeeRegion

EmployeeRegion is a weak entity with a composite key from the tables Region and Employee.

I have an employee profile where they can add themselves to a region. They get a drop down with the regions

enter image description here

I'm doing a pass where I get everything in the model compliant with the data validation stuff that's built in to Asp.net MVC. This is great because the validation (using annotations) shows really great error messages to the end user.

How, using annotations, can I validate that a composite key is unique, and if not, show an error message?

5
  • Give your table (and entity) a composite unique index. Commented Mar 6, 2017 at 18:40
  • Can you elaborate? Commented Mar 6, 2017 at 18:53
  • Can you show what your entity looks like first? Commented Mar 6, 2017 at 18:54
  • 1
    I'm confused. This is basically a M2M, but it doesn't appear that you have any payload. If there's no payload, then you can dispense with the explicit EmployeeRegion entity entirely and just let EF handle the relationship implicitly. Commented Mar 6, 2017 at 19:00
  • There is a payload, it's an enabled/disabled toggle. Payload doesn't matter on create, because we want default enabled. Commented Mar 7, 2017 at 19:33

1 Answer 1

1

Basically, you just need:

public class EmployeeRegion
{
    [Key, Column(Order = 1)]
    public int EmployeeId { get; set; }
    public virtual Employee Employee { get; set; }

    [Key, Column(Order = 2)]
    public int RegionId { get; set; }
    public virtual Region Region { get; set; }
}

In other words, the part you're missing is [Key, Column(Order = N)]. This makes the ids an actual composite key, which out of the box won't allow duplicates.

However, all this does is make the API more difficult for working with this M2M relationship. If the only data in the table is the keys and there's no payload of additional data needed for the relationship, then you should get rid of this entity and simply let EF handle the relationship:

public class Employee
{
    ...

    public virtual ICollection<Region> Regions { get; set; }
}

public class Region
{
    ...

    public virtual ICollection<Employee> Employees { get; set; }
}

Behind the scenes, EF will create a table similar to what you have with EmployeeRegion, but you won't be responsible for managing that, and things like ensuring unique relationships will be baked in. This also buys you a much easier API to work with. For example. To get all the employees for a region, currently, you'd have to do something like:

dbo.EmployeeRegions.Where(m => m.Region.Id == regionId).Select(m => m.Employee)

Whereas, by allowing EF to handle it, you can just do:

region.Employees
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.