Click here to Skip to main content
Click here to Skip to main content

Entity Framework Code First

, 26 May 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
Unique constraints
I just wanted to share a little tip here.
 
So far, in Entity Framework CTP 5, I think RTW does not implement a Unique Constraint for a given column. This is a major issue, I think, as it should mirror database capabilities, but that's another story.
 
This is what I did in my current project. I created an attribute where you can list the name of the fields that need to be flagged as Unique in your POCO, add this attribute to the POCO in question and finally implement a little check on the current object set against the new entity to be added.
The custom attribute looks like this:
 
[System.AttributeUsage(System.AttributeTargets.Class, AllowMultiple=false,Inherited=true)]
public class UniqueAttribute:System.Attribute
{
    private string[] _atts;
    public string[] KeyFields
    {
        get
        {
            return _atts;
        }
    }
    public UniqueAttribute(string keyFields)
    {
        this._atts = keyFields.Split(new char[]{','}, StringSplitOptions.RemoveEmptyEntries);
    }
}
 
Then, we implement it like this:
 
[CustomAttributes.Unique("Name")]
public class Item: BasePOCO
{
    public string Name{get;set;}
    [StringLength(250)]
    public string Description { get; set; }
    [Required]
    public String Category { get; set; }
    [Required]
    public string UOM { get; set; }
}
 
Finally, I added this check on my Add method for my repository, we need to rely on reflection here of course, retrieving the values of the new entity and compare against the current set:
private void ValidateDuplicatedKeys(T entity)
{
    var atts = typeof(T).GetCustomAttributes(typeof(UniqueAttribute), true);
    if (atts == null || atts.Skip(1).Any())
    {
        return;
    }
    foreach (var att in atts)
    {
        UniqueAttribute uniqueAtt = (UniqueAttribute)att;
        var newkeyValues = from pi in entity.GetType().GetProperties()
                            join k in uniqueAtt.KeyFields on pi.Name equals k
                            select new { KeyField = k, Value = pi.GetValue(entity, null).ToString() };
        foreach (var item in _objectSet)
        {
            var keyValues = from pi in item.GetType().GetProperties()
                            join k in uniqueAtt.KeyFields on pi.Name equals k
                            select new { KeyField = k, Value = pi.GetValue(item, null).ToString() };
            var exists = keyValues.SequenceEqual(newkeyValues);
            if (exists)
            {
                throw new System.Exception("Duplicated Entry found");
            }
        }
    }
}
 
Hope this gets you going and saves a little headache or 2 Big Grin | :-D

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Soulus83
Technical Lead
United States United States
No Biography provided

Comments and Discussions

 
GeneralWhere does the "_objectSet" in the statement: "foreach (var ... PinmemberAnHund13-Sep-11 9:05 
GeneralReason for my vote of 4I don't see many examples of how to ... [modified] PinmemberBruce Patin3-Jun-11 5:36 
Reason for my vote of 4 (good):
I don't see many examples of how to create a custom attribute.

modified 13-Aug-12 11:11am.

GeneralExcellent! Updated, thanks a lot! PinmemberSoulus8326-May-11 7:20 
Generalif (atts == null || atts.Count() < 1) should be if (atts ... PinmemberRyanMantha26-May-11 6:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.141015.1 | Last Updated 26 May 2011
Article Copyright 2011 by Soulus83
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid