How to add unique non primary-key field to entity using Entity Framework 4.1? - entity-framework

We are using Entity Framework 4.1 Code first.
We've got user entity with primary key set to UserId and need UserLogin to be unique. How can it be done?

Entity Framework does not support Unique constraints. You can create them using a SQL Query to generate unique constrains when initializing the database. Write your custom initializer for the model and execute SQL command to generate constrain.
Edit
Now (EF 6.1 onwards )you can easily have unique constrains ,
[Index("UserLoginIndex", IsUnique = True)]
public string UserLogin { get; set; }

Check out the unique constraints, I think that's what you're looking for?
http://weblogs.asp.net/manavi/archive/2011/01/23/associations-in-ef-code-first-ctp5-part-3-one-to-one-foreign-key-associations.aspx

Related

One to One Relationship between primary key and unique key in EF6

I'm trying to create a One-to-One relationship between two tables using a primary key and a unique key of the two tables (rather the primary keys).
The following is what I'd like to work.
// The principal end
public class A
{
// The primary Key
public int AId { get; set; }
// The navigation property
public virtual B B { get; set; }
}
// The dependent end
public class B
{
// The primary Key
public int BId { get; set; }
// The unique key
[Index(IsUnique = true)]
public int AId { get; set; }
// The navigation property
public virtual A A { get; set; }
}
But then I see this error:
Unable to determine the principal end of an association between the types 'A' and 'B'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.
I'm quite sure a primarykey-uniquekey relationship is allowed in SQL Server. Looks like EF6 doesn't support it. EF Core 1.0 seems to, but it's not feasible to port to EF Core right now.
Why we need a need a relationship of this kind:
We have two tables A and B in production, but the one-to-one relationship, which should have been there is missing. The relationship is something we need so we can navigate from an A object to a B object with EF. Since both tables have values, we can't really make the primary key, the foreign key - we'll end up with incorrect data.
My approach to fixing this was to:
add a column
fill it with the correct A ids
make it unique
establish the 1-1 relationship
An alternate approach to fixing this is more than welcome.
This is possible with EF Core using Fluent API's .HasPrincipalKey() method. Unfortunately not supported in EF6 which is a shame as relationships over unique keys can essentially be treated the same as foreign key constrains so I'd imagine it would have been an easy addition.
Now that MS has forgot about EF6 and is focusing on EF Core, this will never happen. I really liked using the visual entity designers as it saved so much time. Looking at the thousand+ lines of code the EF Core DbContext scaffold generator spits out for me is discouraging to say the least. Sure, it's pretty when you're dealing with a demo project consisting of two cute tables but we all know this is never the case in the real world. The whole point of using an ORM is to save time but I'm not sure if having to manage thousands of lines of configuration code is any better. Just by two cents.

Entity Framework association with Data Annotations in MVC

I am a newbie in EF, i created a demo application in which i Assigned [StringLength] attribute to model.
[Required]
[StringLength(10)]
public string CustomerName { get; set; }
This worked fine with my EF-Code First approach.
But if i am removing this attribute, then the EF is throwing exception.
I want to know the association which EF created with these attributes
StringLength attribute can be applied to a string type property of a class. EF Code-First will set the size of a column as specified in StringLength attribute. Note that it can also be used with ASP.Net MVC as a validation attribute.
Source
When you don't specify a length, EF Code-First will generate a VARCHAR(MAX)column for your strings. Thats the missmatch you get when you first create the column with StringLength(10) and remove it afterwards.

EF 5 will not set a PK property to IsIdentity to false

The answer in this thread is not working for me.
I put this annotation on the PK in my customer class like so.
public class Customer
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
[Required]
public string Name { get; set; }
}
The database migration creates a configuration showing this one line for the newly added data annotation:
AlterColumn("dbo.Customers", "Id", c => c.Int(nullable: false));
I run the migration and look at the table in SQL Server Management Studio. The customer Id column still has Identity Specification Yes and Is Identity Yes. What am I doing wrong?
Thanks.
You are not doing anything wrong. That is a limitation (or maybe it can be considered as a bug) of migrations because SQL server doesn't allow changing IDENTITY on existing columns. It can be set only on new columns. If you change identity value in management studio it will internally execute some complex SQL batch involving temporary table and a lot of data manipulation.
The simplest solution is to delete your database and remove identity definition from your initial migration. Otherwise use SQL profiler to see what SQL management studio is doing when changing column's identity value and use that SQL in your migration instead of AlterColumn.
The EF treats the Id field as a PK, and a PK must have unique values. That what Identity Specification means. Table Column Properties
Setting DatabaseGeneratedOption.None only specifies that the Id will not be generated by the DB Engine, and you will have to provided it (which I don't think is a good idea).

Why is entity framework not annotating some non nullable columns as required?

I am using EF 4.1 with database first.
Example table:
CREATE TABLE dbo.Foo(
[ID] [int] IDENTITY(1,1) NOT NULL,
Created datetime not null default(getdate()),
Title varchar(80) not null
PRIMARY KEY CLUSTERED ([ID] ASC)
)
EF correctly loads the model with all 3 columns as nullable = false.
Output from code generation item "ADO.NET DbContext Generator":
public partial class Foo
{
public int ID { get; set; }
public System.DateTime Created { get; set; }
public string Title { get; set; }
}
In MVC3 I generate the FooController via the db context and foo model. When I bring up /Foo/Create and hit "Create" on the blank form it shows a validation error on "Created" field but not on "Title".
If I enter only a "created" date I get an exception:
Validation failed for one or more entities. See 'EntityValidationErrors'
property for more details
The exception is "The Title field is required".
I'm not sure why it works fine for one column but not the other. My first fix was to simply add the annotation, however the class code is auto generated by EF.
The only fix that seems to work is to use a partial metadata class: ASP.NET MVC3 - Data Annotations with EF Database First (ObjectConext, DbContext)
I can add the [Required] tag as desired however this should be unnecessary. Is this a bug in EF or am I just missing something?
This isn't a bug, EF simply doesn't add those attributes. As far as i know, the database-first approach (Entity classes generated by the designer) doesn't even perform the validation. The link you're refering to is a valid solution for your problem. The principle of buddy-classes which contain the actual metadata was introduced due to the fact, that you cannot add attributes to existing properties in a partial class.
The code-first approach has a built-in functionality to validate your annotations, see: Entity Framework 4.1 Validation. Another solution when using database-first would be to create a custom code-generator that applies those attributes T4 Templates and the Entity Framework.

Why does Entity Framework make certain fields EnityKeys when they are not even PK's in the source DB?

Starting out on an Entity Framework project.
Imported the Db I am going to use and right away noticed that many table fields were made into EntityKey types and the source fields are not even Keys. Doesn't seem to be a pattern as to which fields were made EntityKeys and which were not.
Is this normal? There were no options for this in the wizard. I don;t want to have to go through and remove this property for all the fields where it was added.
Thanks for your advice!
Each entity on your model requires a unique key, so EF can track and retrieve/persist these entities based on their unique identifier.
If your tables in your database don't have primary keys, then your database is not relational and therefore should not be used by an ORM like EF which is predominantly designed for RDBMS.
If you had an entity like this:
public class Orders
{
public string Name { get; set; }
public double Price { get; set; }
}
How would you retrieve a single order? How would you save a single order?
Crucial LINQ methods such as SingleOrDefault() would be useless, as there is no guarantee that this won't throw an exception:
var singleOrder = ctx.Orders.SingleOrDefault(x => x.Name == "Foo");
Whilst if you had an EntityKey and PK called "OrderId", this is guaranteed to not throw an exception:
var singleOrder = ctx.Orders.SingleOrDefault(x => x.OrderId == 1);
http://msdn.microsoft.com/en-us/library/dd283139.aspx
I think as soon as you read the first paragraph you will understand the role of entity keys in Entity Framework.