An error occurred while saving entities that do not expose foreign key properties for their relationships

93,641

Solution 1

For those of you who would still have this error with all keys properly defined, have a look at your entities and make sure you don't leave a datetime field with a null value.

Solution 2

This error message can be thrown for any kind of reason. The 'InnerException' property (or its InnerException, or the InnerException of that, etc) contains the actual primary cause of the problem.

It would of course be useful to know something about where the problem occurred - which object(s) in the unit of work is causing the problem? The exception message would normally tell you in the 'EntityEntries' property, but in this case, for some reason, that can't be done. This diagnostic complication - of the 'EntityEntries' property being empty - is apparently because some Entities 'do not expose foreign key properties for their relationships.'

Even if the OP gets the error because of failing to initialize DateTimes for the second instance of User, they get the diagnostic complication - 'EntityEntries' being empty, and a confusing top-level message ... because one of their Entity's doesn't 'expose foreign key properties'. To fix this, Avatar should have a public virtual ICollection<User> Users { get; set; } property defined.

Solution 3

The issue was resolved by adding an FK property.

Solution 4

In my case the following situation was giving me the same Exception:

Imagine a code first EF model where you have a Garage entity that has a collection of Car entities. I needed to remove a car from the garage so I ended up with code that looked like this:

garageEntity.Cars.Remove(carEntity);

Instead, it should've been looked like this:

context.Cars.Remove(carEntity);

Solution 5

In my case the exeception was thrown because EF had created a migration incorrectly. It missed setting the identity: true on the second table. So go into the migrations which created the relevant tables and check if it missed to add identity.

CreateTable(
    "dbo.LogEmailAddressStats",
    c => new
        {
            Id = c.Int(nullable: false, identity: true),
            EmailAddress = c.String(),
        })
    .PrimaryKey(t => t.Id);

CreateTable(
    "dbo.LogEmailAddressStatsFails",
    c => new
        {
            Id = c.Int(nullable: false), // EF missed to set identity: true!!
            Timestamp = c.DateTime(nullable: false),
        })
    .PrimaryKey(t => t.Id)
    .ForeignKey("dbo.LogEmailAddressStats", t => t.Id)
    .Index(t => t.Id);

An Id column should have identity (i.e. auto-incrementing!) so this must be a EF bug.

You could add identity manually with SQL directly to the database but I prefer using Entity Framework.

If you run in to the same problem I see two easy solutions:

Alt 1

reverse the incorrectly created migration with

update-database -target:{insert the name of the previous migration}

Then add the identity: true manually to the migration code and then update-database again.

Alt 2

you create a new migration that adds identity. If you have no changes in the models and you run

add-migration identity_fix

it will create an empty migration. Then just add this

    public partial class identity_fix : DbMigration
    {
        public override void Up()
        {
            AlterColumn("dbo.LogEmailAddressStatsFails", "Id", c => c.Int(nullable: false, identity: true));
        }

        public override void Down()
        {
            AlterColumn("dbo.LogEmailAddressStatsFails", "Id", c => c.Int(nullable: false));
        }
    }
Share:
93,641
user278618
Author by

user278618

Updated on May 19, 2021

Comments

  • user278618
    user278618 almost 3 years

    I have a simply code in Entity Framework 4.1 code first:

    PasmISOContext db = new PasmISOContext();
    var user = new User();
    user.CreationDate = DateTime.Now;
    user.LastActivityDate = DateTime.Now;
    user.LastLoginDate = DateTime.Now;
    db.Users.Add(user);
    
    db.SaveChanges();
    user.Avatar = new Avatar() { Link = new Uri("http://myUrl/%2E%2E/%2E%2E") };
    db.SaveChanges();
    
    
    db.Users.Add(new User() { Avatar = new Avatar() { Link = new Uri("http://myUrl/%2E%2E/%2E%2E") } });
    db.SaveChanges();
    

    The problem is that I get an error

    An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.

    at

    db.Users.Add(new User() { Avatar = new Avatar() { Link = new Uri("http://myUrl/%2E%2E/%2E%2E") } });
    db.SaveChanges();
    

    I don't understand why the similar operation works. Is there something wrong with my model, or with ef-code-first?

    public class Avatar
    {
        [Key]
        public int Id { get; set; }
    
        [Required]
        public string LinkInString { get; set; }
    
        [NotMapped]
        public Uri Link
        {
            get { return new Uri(LinkInString); }
            set { LinkInString = value.AbsoluteUri; }
        }
    }
    
    public class User
    {
        [Key]
        public int Id { get; set; }
        public string UserName { get; set; }
        public string Email { get; set; }
        public string Password { get; set; }
        public Avatar Avatar { get; set; }
        public virtual ICollection<Question> Questions { get; set; }
        public virtual ICollection<Achievement> Achievements { get; set; }
    
        public DateTime CreationDate { get; set; }
        public DateTime LastLoginDate { get; set; }
        public DateTime LastActivityDate { get; set; }
    }