Unique Key with Ef Code First

Unique Key constraints for multiple columns in Entity Framework

With Entity Framework 6.1, you can now do this:

[Index("IX_FirstAndSecond", 1, IsUnique = true)]
public int FirstColumn { get; set; }

[Index("IX_FirstAndSecond", 2, IsUnique = true)]
public int SecondColumn { get; set; }

The second parameter in the attribute is where you can specify the order of the columns in the index.

More information: MSDN

Entity Framework Core add unique constraint code-first

On EF core you cannot create Indexes using data annotations.But you can do it using the Fluent API.

Like this inside your {Db}Context.cs:

protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<User>()
.HasIndex(u => u.Email)
.IsUnique();
}

...or if you're using the overload with the buildAction:

protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<User>(entity => {
entity.HasIndex(e => e.Email).IsUnique();
});
}

You can read more about it here : Indexes

Define an Unique Key in Entity Framework code-first approch

Most likely, the problem lies in the fact that by default, EF code-first will make all string fields into VARCHAR(MAX) in the database - which cannot be indexed (since it's more than 900 bytes in size).

You probably only need to define a string length (which would be a good idea for all your string fields!):

public class Author
{
public Author()
{
}

[Key]
public int Auth_Id { get; set; }

[StringLength(100)]
public string First_Name { get; set; }

[Index("IX_FirstAndSecond", 1, IsUnique = true)]
[StringLength(100)]
public string Last_Name { get; set; }

public string Biography { get; set; }
}

So now your First_Name and Last_Name columns should be VARCHAR(100) in the database table, and the index should be applied just fine.

Unique key with EF code first

Unfortunately you can't define it as unique key in code first because EF doesn't support unique keys at all (it is hopefully planned for next major release). What you can do is to create custom database intializer and add unique index manually by calling SQL command:

public class MyInitializer : CreateDatabaseIfNotExists<MyContext>
{
protected override void Seed(MyContext context)
{
context.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX IX_Category_Title ON Categories (Title)");
}
}

And you must set this initializer in the bootstrap of your application.

Database.SetInitializer<MyContext>(new MyInitializer());

Edit

Now (EF 6.1 onwards )you can easily have unique constrains ,

[Index("TitleIndex", IsUnique = true)]
public string Title { get; set; }

Entity Framework Code first : Set unique key constraint is not working

From EF Core Documentation:

Indexes can not be created using data annotations.

But you can use the fluent API to create index :

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>()
.HasIndex(c => c.EmailAddress) // Create an index
.IsUnique() // that is unique
.ForSqlServerHasName("IX_EA"); // specify the name
}

You can also use Alternate keys

An alternate key serves as a alternate unique identifier for each entity instance in addition to the primary key. When using a relational database this maps to the concept of a unique index/constraint. In EF, alternate keys provide greater functionality than unique Indexes because they can be used as the target of a foreign key.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>()
.HasAlternateKey(c => c.EmailAddress);
}

Entity Framework Code First unique index foreign key throws DbUpdate Exception

Entity framework is re-adding your Owner(Member). There are a couple of ways around this, but since you have the FK try this:

public class Bicycle
{
public int BicycleID { get; set; }

public int MemberID { get; set; } // You can call this ownerId, but then you need to setup the relationship with annotation or fluent
public virtual Member Owner { get; set; }
}

public void bicycle_set_FK(int IDbicycle, int IDmember)
{
var bicycleToFind = BicycleDB.Find(IDbicycle);
// var memberToSetAsFK = MemberDB.Find(IDmember); ** Don't need to do this since you have FK **
bicycleToFind.MemberId = IDmember;
SaveChanges();
}

See https://msdn.microsoft.com/en-us/magazine/dn166926.aspx?f=255&MSPPError=-2147217396

EDIT: First, I highly recommend you follow some convention when naming your navigation classes and keys. You are calling your navigation class "MemberId" - that is very confusing. If you want the FK to be OwnerId, go with something like this:

public int? OwnerID { get; set; }

[ForeignKey("OwnerID")]
public virtual Member Owner { get; set; }

Second, you don't need this annotation:

//[Index("MemberUniqueID", IsUnique = true)]  **MemberID will be a identity key by default so it will have a unique index created.
public int MemberID { get; set; }

Now you can insert an existing owner like this:

public void bicycle_set_FK(int IDbicycle, int IDmember)
{
var bicycleToFind = BicycleDB.Find(IDbicycle);
bicycleToFind.OwnerID = IDmember; // Don't worry about the nav class, just set the FK
SaveChanges();
}

Regarding the one to many, you already have that configured with:

public virtual ICollection<Member> FamilyMembers { get; set; }

So to add a new member:

var newMember = new Member {
Name = "Joe",
Surname = "Smith",
Age = 30,
FamilyId = familyId
};

context.Members.Add(newMember);
SaveChanges();

How to specify Unique Key in EF 7 Code First with Data Annotations

I'm afraid create an Index using Data Annotation is not still supported in EF 7. Check this link.

I also tried to find some info related with that subject in the last releases and I couldn't find anything.

EF 7 beta 8 release notes

EF 7 RC1 release notes

I found now a post from one of the EF developers (divega) saying this:

In EF7 we support defining indexes using the fluent API but not an
attribute, at least no yet. The IndexAttribute you are possibly
referring to is something we added to the EF 6.x package at some point
but never really became a standard DataAnnotation.

We don't want to copy the original attribute from EF6 as is because
there are a few things in it that we would like to change. Also,
having it in DataAnnotations directly would likely make more sense
than adding it to the EF7 package.
I should mention though that it is highly unlikely that we will add
IndexAttribute in the EF7 RTM timeframe.

Update 1

Apparently this is a feature that will not be added to EF Core, at least for now.

From EF Core documentation:

Indexes can not be configured using Data Annotations.

But you can do it using Fluent Api:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasIndex(b => b.Url)
.HasName("Index_Url");
}

Unique Constraint in Entity Framework Code First

As far as I can tell, there's no way to do this with Entity Framework at the moment. However, this isn't just a problem with unique constraints... you may want to create indexes, check constraints, and possibly triggers and other constructs too. Here's a simple pattern you can use with your code-first setup, though admittedly it's not database agnostic:

public class MyRepository : DbContext {
public DbSet<Whatever> Whatevers { get; set; }

public class Initializer : IDatabaseInitializer<MyRepository> {
public void InitializeDatabase(MyRepository context) {
if (!context.Database.Exists() || !context.Database.ModelMatchesDatabase()) {
context.Database.DeleteIfExists();
context.Database.Create();

context.ObjectContext.ExecuteStoreCommand("CREATE UNIQUE CONSTRAINT...");
context.ObjectContext.ExecuteStoreCommand("CREATE INDEX...");
context.ObjectContext.ExecuteStoreCommand("ETC...");
}
}
}
}

Another option is if your domain model is the only method of inserting/updating data in your database, you could implement the uniqueness requirement yourself and leave the database out of it. This is a more portable solution and forces you to be clear about your business rules in your code, but leaves your database open to invalid data getting back-doored.

Is it possible to set a unique constraint using Entity Framework Code First?

It appears that the unique constraint feature that was scheduled to release with Version 6 got pushed to 6.1.

With EF 6.1, you can define a constraint using the Index attribute as shown below:

[Index("IX_FirstAndSecond", 1, IsUnique = true)]
public int FirstColumn { get; set; }

[Index("IX_FirstAndSecond", 2, IsUnique = true)]
public int SecondColumn { get; set; }

OR

You can use Fluent API as shown here in MSDN



Related Topics



Leave a reply



Submit