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
JSON.Net Throws Stackoverflowexception When Using [JSONconvert()]
Why Do Assignment Statements Return a Value
Open Existing File, Append a Single Line
Design - Where Should Objects Be Registered When Using Windsor
Entity Framework (Ef) Code First Cascade Delete for One-To-Zero-Or-One Relationship
Difference Between Observablecollection and Bindinglist
How to Detect If Console.In (Stdin) Has Been Redirected
How to Compare 2 Files Fast Using .Net
ASP.NET Core Web API Exception Handling
How to Use Moq to Mock an Extension Method
How to Bind a List to a Combobox
Assigning Out/Ref Parameters in Moq
How to Deserialize a Child Object with Dynamic (Numeric) Key Names
Add New Item in Existing Array in C#.Net