Reputation:
EF 6, VS 2013, Local DB.
I have a very basic Entity Framework test project. It has Users
and Blogs
.
Every user can have many blogs, and a blog has a foreign key relating to the user.
I create a User
, and a blog, but I don't connect them. EF made the connection without me telling it to.
If I don't create the User
object, it errors as I wanted it to. I.e. don't save an object missing a required field.
public class FieldSizes
{
public const int Names = 32;
public const int Long = 80;
}
class Program
{
static void Main(string[] args)
{
using(Dbf db = new Dbf())
{
var user = db.Users.Create();
user.PasswordHash = "tests";
user.UserName = "sssss";
db.Users.Add(user);
var blog = db.Blogs.Create();
blog.Title = "gssss";
blog.ContentId = 42;
db.Blogs.Add(blog);
db.SaveChanges();
}
}
}
public class Dbf : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Blog> Blogs { get; set; }
}
public class User
{
[Key]
public int Id { get; set; }
[MaxLength(FieldSizes.Names)]
public string UserName { get; set; }
public string PasswordHash { get; set; }
public void SetPassword(string password)
{
this.PasswordHash = "[Encryption Key]";
}
public virtual List<Blog> Blogs { get; set; }
}
public class Blog
{
[Key]
public int Id { get; set; }
[ForeignKey("User")]
public int UserId { get; set; }
public virtual User User { get; set; }
[MaxLength(FieldSizes.Long)]
public string Title { get; set; }
public int ContentId { get; set; }
}
Is this by design in EF? Is there a mistake in my code? I don't understand why EF is doing this.
Upvotes: 2
Views: 189
Reputation: 14640
Yes, it's by design, but it's something that will be a problem if we're not aware about it.
When you created a new User
, EF will assign a temporary key as primary key. The newly created User
will have temporary Id = 0 since it's a default value of integer. The key is a temporary key and if it's an identity key, it will be updated after it's saved.
More: EntityKey.IsTemporary.
And when you created a new Blog
, the default value of UserId
is also 0. And it will cause Blog
and User
have relationship in the database.
You can also assign temporary key manually to make a relationship.
user.Id = 1234;
blog.UserId = 1234;
This is a great article explaining about this case. Here is part of the excerpt.
When creating a new relation we just need a dependent entity and a primary key of a parent entity. The tricky part here is that primary key must be unique for all attached entities of a given type. Even if we use auto generated keys in the database we must still assign temporary unique key to newly created entities which are added to relations.
Upvotes: 1