Ошибка при сохранении сущностей не обеспечивающих доступ к свойствам внешнего ключа для их связей

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));
        }
    }

(I’ve checked the related questions, and can’t find an answer.)

I’m doing some tests with Code First Entity Framework 6.
I have a «Child» entity that references two «Parent» entities.

I want to create the child entity and parent entities, and then save them all at once (so I can cut down on the number of db.Save() calls, and to keep it as one unit of work).

public class Child
{
    public int ChildID { get; set; }
    public string Name { get; set; }

    public virtual Parent Father { get; set; }
    public virtual Parent Mother { get; set; }
}

public class Parent
{
    public int ParentID { get; set; }
    public string Name { get; set; }

    [ForeignKey("Child")]
    public int? ChildID { get; set; }
    public virtual Child Child { get; set; }
}

(A bit of a confusing setup — the parents are actually the «children» of the child in the relationship. I know it’s bad abstraction. This is just a test.)

Controller:

    public ActionResult AddWithParents()
    {
        Parent father = new Parent { Name = "Test Father" };
        Parent mother = new Parent { Name = "Test Mother" };

        Child newChild = new Child
        {
            Name = "Test Child",
            Father = father,
            Mother = mother
        };


        db.Children.Add(newChild);

        father.Child = newChild;
        mother.Child = newChild;

        db.SaveChanges();            

        return RedirectToAction("Index");
    }

This works, but doesn’t populate the Parent.ChildID foreign key.

If I do something like father.Child = newChild, I get the following 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.
Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values.

Is there any way to get this to work?

(I’ve checked the related questions, and can’t find an answer.)

I’m doing some tests with Code First Entity Framework 6.
I have a «Child» entity that references two «Parent» entities.

I want to create the child entity and parent entities, and then save them all at once (so I can cut down on the number of db.Save() calls, and to keep it as one unit of work).

public class Child
{
    public int ChildID { get; set; }
    public string Name { get; set; }

    public virtual Parent Father { get; set; }
    public virtual Parent Mother { get; set; }
}

public class Parent
{
    public int ParentID { get; set; }
    public string Name { get; set; }

    [ForeignKey("Child")]
    public int? ChildID { get; set; }
    public virtual Child Child { get; set; }
}

(A bit of a confusing setup — the parents are actually the «children» of the child in the relationship. I know it’s bad abstraction. This is just a test.)

Controller:

    public ActionResult AddWithParents()
    {
        Parent father = new Parent { Name = "Test Father" };
        Parent mother = new Parent { Name = "Test Mother" };

        Child newChild = new Child
        {
            Name = "Test Child",
            Father = father,
            Mother = mother
        };


        db.Children.Add(newChild);

        father.Child = newChild;
        mother.Child = newChild;

        db.SaveChanges();            

        return RedirectToAction("Index");
    }

This works, but doesn’t populate the Parent.ChildID foreign key.

If I do something like father.Child = newChild, I get the following 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.
Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values.

Is there any way to get this to work?

We are using MVC in combination with Entity Framework.

At some point we are trying to establish a link between two entities.  This works fine in a unit-test, but gives the following error when tried from an MVC controller method:

“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. “

The (stripped down) classes:

public class Position : Entity
{
   public string Function { get; set; }
   public Organization Organization{ get; set; }
   // public Guid? OrganizationId { get; set; }
   // works when enabled!
}

public class Organization: Entity
{
   public string Name { get; set; } 
   public IList<Position> Contacts
   {
       get {return contacts;} 
       set { contacts = value; }
   }
 
   public class EntityConfiguration :
            EntityConfigurationBase<Organization>
   {
       public EntityConfiguration()
       {
           HasMany(p => p.Contacts)
               .WithOptional(y => y.Organization)
        }
   }
 
   private IList<Position> contacts = 
       new List<Position>();
}

The (stripped down) controller method that fails:

[HttpPost]
public ActionResult Edit(Position position, string organizationId = "")
{
    if (!ModelState.IsValid)
    {
        return View(position);
    }
    db.Entry(position).State = EntityState.Modified;
    if (!string.IsNullOrEmpty(organizationId))
    {
        Guid orgId = Guid.Parse(organizationId);
        Organization organization =
            db.Organizations
                .First(x => x.Id.Equals(orgId));
        position.Organization = organization;
    }
	db.SaveChanges();
    RedirectToAction("Index");
}

The unit test that passes:

[TestMethod]
public void LinkOrganizationToPositionTest()
{
    // arrange
    DbModel dbModel;
    Organization org;
    Position pos;
    Guid orgId;

    using (dbModel = new DbModel())
    {
        dbModel.Database.Delete();
        dbModel.Database.Create();

        // - first organization
        org = dbModel.Organizations.Create();
        org.Name = "TestOrgFirst";
        dbModel.Entry(org).State = EntityState.Added;

        pos = dbModel.Positions.Create();
        pos.Function = "TestFunc";
        dbModel.Entry(pos).State = EntityState.Added;

        // - link pos to first org
        pos.Organization = org;

        org = dbModel.Organizations.Create();
        org.Name = "TestOrgSecond";
        dbModel.Entry(org).State = EntityState.Added;
        orgId = org.Id;
        dbModel.SaveChanges();
    }

    // act
    // - obtain "fresh" model
    using (dbModel = new DbModel())
    {
        // - get second org
        org = dbModel.Organizations.Find(orgId);
        pos = dbModel.Positions.Find(pos.Id);
        pos.Organization = org;
        dbModel.SaveChanges();
    }

    // assert
    using (dbModel = new DbModel())
    {
        Position actual =
            dbModel.Positions
                .Include("Organization")
                    .First(x => x.Id.Equals(pos.Id));
        // - link was saved 
        Assert.AreEqual(
            "TestOrgSecond", 
            actual.Organization.Name
            );
    }
}

Why is the is the OrganizationId foreign key property required by the MVC?
 Is there a simple fix that doesn’t require  all the foreign-keys in the model?

We are using MVC in combination with Entity Framework.

At some point we are trying to establish a link between two entities.  This works fine in a unit-test, but gives the following error when tried from an MVC controller method:

“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. “

The (stripped down) classes:

public class Position : Entity
{
   public string Function { get; set; }
   public Organization Organization{ get; set; }
   // public Guid? OrganizationId { get; set; }
   // works when enabled!
}

public class Organization: Entity
{
   public string Name { get; set; } 
   public IList<Position> Contacts
   {
       get {return contacts;} 
       set { contacts = value; }
   }
 
   public class EntityConfiguration :
            EntityConfigurationBase<Organization>
   {
       public EntityConfiguration()
       {
           HasMany(p => p.Contacts)
               .WithOptional(y => y.Organization)
        }
   }
 
   private IList<Position> contacts = 
       new List<Position>();
}

The (stripped down) controller method that fails:

[HttpPost]
public ActionResult Edit(Position position, string organizationId = "")
{
    if (!ModelState.IsValid)
    {
        return View(position);
    }
    db.Entry(position).State = EntityState.Modified;
    if (!string.IsNullOrEmpty(organizationId))
    {
        Guid orgId = Guid.Parse(organizationId);
        Organization organization =
            db.Organizations
                .First(x => x.Id.Equals(orgId));
        position.Organization = organization;
    }
	db.SaveChanges();
    RedirectToAction("Index");
}

The unit test that passes:

[TestMethod]
public void LinkOrganizationToPositionTest()
{
    // arrange
    DbModel dbModel;
    Organization org;
    Position pos;
    Guid orgId;

    using (dbModel = new DbModel())
    {
        dbModel.Database.Delete();
        dbModel.Database.Create();

        // - first organization
        org = dbModel.Organizations.Create();
        org.Name = "TestOrgFirst";
        dbModel.Entry(org).State = EntityState.Added;

        pos = dbModel.Positions.Create();
        pos.Function = "TestFunc";
        dbModel.Entry(pos).State = EntityState.Added;

        // - link pos to first org
        pos.Organization = org;

        org = dbModel.Organizations.Create();
        org.Name = "TestOrgSecond";
        dbModel.Entry(org).State = EntityState.Added;
        orgId = org.Id;
        dbModel.SaveChanges();
    }

    // act
    // - obtain "fresh" model
    using (dbModel = new DbModel())
    {
        // - get second org
        org = dbModel.Organizations.Find(orgId);
        pos = dbModel.Positions.Find(pos.Id);
        pos.Organization = org;
        dbModel.SaveChanges();
    }

    // assert
    using (dbModel = new DbModel())
    {
        Position actual =
            dbModel.Positions
                .Include("Organization")
                    .First(x => x.Id.Equals(pos.Id));
        // - link was saved 
        Assert.AreEqual(
            "TestOrgSecond", 
            actual.Organization.Name
            );
    }
}

Why is the is the OrganizationId foreign key property required by the MVC?
 Is there a simple fix that doesn’t require  all the foreign-keys in the model?

Произошла ошибка при сохранении сущностей, которые не предоставляют свойства внешнего ключа для их связей

у меня есть просто код в Entity Framework 4.1 код:

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();

проблема в том, что я получаю ошибку

произошла ошибка при сохранении объектов, которые не предоставляют внешний ключ
свойства для их отношений. Свойство EntityEntries будет
возвращает null, так как один объект не может быть идентифицирован как источник
исключение. Обработка исключений при сохранении может быть выполнена
проще, предоставляя свойства внешнего ключа в типах сущностей. Видеть
исключение InnerException для деталей.

at

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

Я не понимаю, почему подобные операции. Что-то не так с моей моделью, или с EF код-первый?

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; }
}

14 ответов


для тех из вас, кто по-прежнему будет иметь эту ошибку со всеми правильно определенными ключами, посмотрите на свои сущности и убедитесь, что вы не оставляете поле datetime со значением null.


это сообщение об ошибке может быть выдано по какой-либо причине. Свойство «InnerException» (или его InnerException, или InnerException этого и т. д.) содержит фактическую первичную причину проблемы.

было бы, конечно, полезно узнать что — то о том, где возникла проблема-какой объект(ы) в единице работы вызывает проблему? Сообщение об исключении обычно сообщает вам в свойстве ‘EntityEntries’, но в этом случае по какой-то причине это не может быть сделанный. Это диагностическое осложнение-свойство «EntityEntries» является пустым-по-видимому, потому, что некоторые сущности » не предоставляют свойства внешнего ключа для своих отношений.’

даже если OP получает ошибку из-за неспособности инициализировать DateTimeS для второго экземпляра User, они получают диагностическое осложнение — «EntityEntries» пустое и запутанное сообщение верхнего уровня … потому что один из их сущностей не «предоставляет свойства внешнего ключа». Фиксировать это Avatar должен быть public virtual ICollection<User> Users { get; set; } собственность определены.


проблема была решена путем добавления свойства FK.


в моем случае следующая ситуация давала мне такое же исключение:

представьте себе код первой модели EF, где у вас есть Garage сущность, которая имеет коллекцию Car объекты. Мне нужно было удалить машину из гаража, поэтому я закончил с кодом, который выглядел так:

garageEntity.Cars.Remove(carEntity);

вместо этого, это должно было выглядеть так:

context.Cars.Remove(carEntity);

только для тех, кто может иметь аналогичные проблемы. У меня была та же ошибка, но по другой причине. В одном из дочерних объектов я определил [Key] как значение, которое было одинаковым для разных сохранений. Глупая ошибка с моей стороны, но сообщение об ошибке не сразу приводит вас к проблеме.


в моем случае exeception был брошен, потому что EF создал миграцию неправильно.
Он пропустил установку идентичность: true на втором столе. Поэтому перейдите в миграции, которые создали соответствующие таблицы, и проверьте, не пропустил ли он добавление идентификатора.

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);

столбец Id должен иметь идентификатор (т. е. автоматическое увеличение!) так что это должно быть ошибка EF.

вы можете добавить идентификатор вручную с SQL непосредственно в базу данных, но я предпочитаю использовать Entity Рамки.

если вы столкнетесь с той же проблемой, которую я вижу два простых решения:

Alt 1

отменить неправильно созданную миграцию с помощью

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

добавить идентичность: true вручную в код миграции, а затем обновление-базы данных снова.

Alt 2

создать новую миграцию, которая добавляет индивидуальности. Если у вас нет изменений в модели и вы бежите

add-migration identity_fix

это создаст пустую миграцию. Тогда просто добавьте это

    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));
        }
    }

эта проблема также может возникнуть из обращенных объявлений ключей. Если вы используете fluent для настройки связи, убедитесь, что левый и правый ключи сопоставлены с правильной сущностью.


еще один ответ:

я использовал этот:

public List<EdiSegment> EdiSegments { get; set; }

вместо этого:

public virtual ICollection<EdiSegment> EdiSegments { get; set; }

и получил сообщение об ошибке, упомянутых выше.


У меня была такая же ошибка, и в моем случае проблема заключалась в том, что я добавил объект отношения, который уже был загружен «AsNoTracking». Мне пришлось перезагрузить свойство relation.

кстати, некоторые предлагают использовать «Attach»для отношений, которые уже существуют в БД, я не пробовал эту опцию.


У меня такая же проблема. в моем случае, это было связано с полем datetime со значением null. Я должен был передать значение datetime, и evrythings пошел хорошо


в моем случае проблема заключалась в том, что я переименовал столбец неправильно, поэтому миграция сделала два столбца, один под названием «TeamId» и один под названием «TeamID». C# заботится, SQL-нет.


еще одно дело здесь.
Запрос был приведен к списку, и при этом он создал сущности своим конструктором для сравнения в выражении linq сразу после ToList (). Это создало сущности, которые попали в удаленное состояние после завершения выражения linq.
Однако! Была небольшая корректировка, которая создала другой объект в конструкторе, так что этот новый объект был связан с объектом, который был помечен как удаленный.

код для проиллюстрировать:

query.Except(_context.MyEntitySetSet()
                .Include(b => b.SomeEntity)
                .Where(p => Condition)
                .ToList() // This right here calls the constructor for the remaining entities after the where
                .Where(p => p.Collection.First(b => Condition).Value == 0)
                .ToList();

конструктор MyEntity:

public partial class MyEntity
{
    protected MyEntity()
    {
        // This makes the entities connected though, this instance of MyEntity will be deleted afterwards, the instance of MyEntityResult will not.
        MyEntityResult = new MyEntityResult(this);
    }
}

мое решение состояло в том, чтобы убедиться, что все выражение было сделано внутри IQueryable, чтобы не было никаких объектов.


Я не совсем уверен, что это поможет в вашем случае, потому что я настраиваю свои таблицы с помощью Fluent API, однако, насколько я могу судить, проблема возникает независимо от того, настроена ли схема с использованием аннотаций данных (атрибутов) или Fluent API (конфигурации).

там, кажется, ошибка в эф (ст. 6.1.3), так как он опускает некоторые изменения в схеме при обновлении БД до следующей миграции. Самый быстрый маршрут вокруг него (на этапе разработки), чтобы удалить все таблицы из БД и миграции runt из этапа инициализации снова.

Если вы уже находитесь в производстве, самым быстрым решением, которое я нашел, было вручную изменить схему в БД или, если вы хотите иметь контроль версий изменений, вручную манипулировать методами Up () и вниз() в вашей миграции.

0

автор: Konrad Viltersten


сегодня я столкнулся с этой проблемой и попробовал возможные решения, опубликованные выше, но никто из них не помог мне. У меня было UnitOfWork шаблон реализован, и система фиксировала данные в последнем после добавления всех записей.

в моем случае система объединяла две модели и запрашивала DB

недопустимое имя объекта ‘ dbo.RoleModelUserModel’.

где на самом деле это были две разные модели.

я исправил это, переупорядочив insert операторы и добавление родительского объекта в первую очередь. В этом случае добавлен пользователь первый и проблема решена.


При попытке вызвать SaveChanges() я получаю следующую ошибку:

Произошла ошибка при сохранении сущностей, которые не предоставляют свойства внешнего ключа для своих связей. Свойство EntityEntries вернет значение null, поскольку один объект не может быть идентифицирован как источник исключения. Обработку исключений при сохранении можно упростить, предоставив свойства внешнего ключа в ваших типах сущностей. Подробности смотрите в InnerException».

SqlException: недопустимое имя столбца «Artwork_Id»

Я использую Entity Framework.

Я пытаюсь добавить artworkImage с идентификатором произведения искусства в качестве ссылки. Вся информация передается корректно, но не сохраняется.

public partial class ArtworkImage
{
    [Key]
    public int Id { get; set; }
    public string ImageURL { get; set; }
    public Artwork Artwork { get; set; }
}

public partial class Artwork
{
    [Key]
    public int Id { get; set; }
    public string Category { get; set; }
    public ICollection<ArtworkImage> ArtworkImage { get; set; }
}

Мой DbContext:

public DbContext()
        : base("name=DbConnection")
    {
        this.Configuration.AutoDetectChangesEnabled = false;
    }

    public virtual DbSet<Artwork> Artworks { get; set; }

    public virtual DbSet<ArtworkImage> ArtworkImages { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Artwork>()
            .Property(e => e.Category)
            .IsFixedLength();

        Database.SetInitializer<DbContext>(null);
        base.OnModelCreating(modelBuilder);
    }

Если какой-либо информации не хватает, укажите ее, и я добавлю ее.

2 ответа

Вы должны объявить первичный ключ для каждой таблицы. это редкий случай, когда таблица не имеет PK. почти никогда.

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


0

Boppity Bop
2 Сен 2022 в 17:25

Таким образом, часть вашей проблемы может заключаться в том, что вы не определяете отношение в обратном порядке, что, я считаю, важно для того, как оно устанавливает, является ли отношение один к одному или один ко многим. Поэтому вам, вероятно, потребуется добавить в класс Artwork свойство типа ArtworkImage (если оно взаимно однозначное). если это один ко многим, вам нужно будет сделать свойство некоторой общей коллекцией с общим типом ArtworkImage.

Один к одному

public partial class Artwork
{
    [Key]
    public int Id { get; set; }
    public string Category { get; set; }
    public ArtworkImage ArtworkImage { get; set; }
}

Один ко многим

public partial class Artwork
{
    [Key]
    public int Id { get; set; }
    public string Category { get; set; }
    public IEnumerable<ArtworkImage> ArtworkImages { get; set; }
}


0

MarkieMark
2 Сен 2022 в 18:21

Для тех из вас, у кого все еще будет эта ошибка при правильном определении всех ключей, взгляните на свои объекты и убедитесь, что вы не оставляете поле datetime с нулевым значением.

Это сообщение об ошибке может быть выдано по любой причине. Свойство InnerException (или его InnerException, или его InnerException и т. Д.) Содержит фактическую основную причину проблемы.

Конечно, было бы полезно узнать что-нибудь о том, где возникла проблема — какой объект (ы) в единице работы вызывает проблему? Сообщение об исключении обычно сообщает вам в свойстве EntityEntries, но в этом случае по какой-то причине это невозможно. Эта диагностическая сложность — пустое свойство EntityEntries — по-видимому, вызвана тем, что некоторые сущности «не раскрывают свойства внешнего ключа для своих отношений».

Даже если OP получает ошибку из-за неспособности инициализировать DateTime s для второго экземпляра User , они получают диагностическое осложнение — EntityEntries пусто и сбивает с толку сообщение верхнего уровня. … потому что одна из их сущностей не «раскрывает свойства внешнего ключа». Чтобы исправить это, в Avatar должно быть определено свойство public virtual ICollection<User> Users { get; set; } .

Проблема была решена добавлением свойства FK.

В моем случае следующая ситуация дала мне такое же исключение:

Представьте себе модель EF с первым кодом, где у вас есть объект Garage который имеет коллекцию объектов Car . Мне нужно было вывести машину из гаража, поэтому я получил код, который выглядел так:

garageEntity.Cars.Remove(carEntity);

Вместо этого это должно было выглядеть так:

context.Cars.Remove(carEntity);

Просто для тех, у кого могут быть похожие проблемы. У меня была такая же ошибка, но по другой причине. В одном из дочерних объектов я определил [Key] как значение, одинаковое для разных сохранений. Глупая ошибка с моей стороны, но сообщение об ошибке не сразу приводит вас к проблеме.

В моем случае исключение было создано из-за того, что EF неправильно создал миграцию. Он пропустил установку идентификатора: true во второй таблице. Итак, войдите в миграции, которые создали соответствующие таблицы, и проверьте, не пропущено ли добавление идентификатора.

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);

Столбец Id должен иметь идентификатор (т.е. автоинкремент!), Так что это должна быть ошибка EF.

Вы можете вручную добавить идентификацию с помощью SQL прямо в базу данных, но я предпочитаю использовать Entity Framework.

Если вы столкнетесь с той же проблемой, я вижу два простых решения :

Альтернативный вариант 1

отменить неправильно созданную миграцию с помощью

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

Затем вручную добавьте идентификатор: true в код миграции, а затем снова обновите базу данных .

Альтернатива 2

вы создаете новую миграцию, которая добавляет идентичность. Если у вас нет изменений в моделях и вы запускаете

add-migration identity_fix

это создаст пустую миграцию. Тогда просто добавьте это

    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));
        }
    }

Эта проблема также может возникнуть из-за перевернутого объявления ключей. Если вы используете Fluent для настройки взаимосвязи, убедитесь, что левая и правая клавиши сопоставлены с правильным объектом.

Другой ответ:

Я использовал это:

public List<EdiSegment> EdiSegments { get; set; }

вместо этого:

public virtual ICollection<EdiSegment> EdiSegments { get; set; }

и получил сообщение об ошибке, указанное выше.

У меня была такая же ошибка, и в моем случае проблема заключалась в том, что я добавил уже загруженный объект отношения «AsNoTracking». Мне пришлось перезагрузить свойство отношения.

Кстати, некоторые предлагают использовать «Attach» для отношений, которые уже существуют в db, но я не пробовал этот вариант.

У меня была такая же проблема. в моем случае это произошло из-за поля datetime с нулевым значением. Мне пришлось перенести значение на datetime, и все прошло нормально

У меня есть простой код в Entity Framework 4.1 сначала код:

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();

Проблема в том, что я получаю сообщение об ошибке

Произошла ошибка при сохранении сущностей, которые не раскрывают свойства внешнего ключа
для своих отношений. Свойство EntityEntries
вернет значение null, поскольку отдельная сущность не может быть идентифицирована как источник
исключения. Обработку исключений при сохранении можно
упростить, предоставив свойства внешнего ключа в типах сущностей. Подробнее см.
InnerException.

в

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

Я не понимаю, почему подобная операция работает. Что-то не так с моей моделью или с 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; }
}

задан abatishchev 13 January 2015 в 19:09

поделиться

Я объявляю некоторые сущности следующим образом:

Entity myEntity = new Entity();
myEntity.InnerProperties = new InnerProperties();
myEntity.OuterProperties = new OuterProperties();

Когда я отлаживаю код, идентификатор myEntity и идентификатор обоих свойств равен 0. Когда я запускаю эти строки:

_context.Entities.Add(myEntity);
_context.SaveChanges();

Я получаю это исключение: {«Произошла ошибка при сохранении объектов, которые не раскрывают свойства внешнего ключа для своих отношений. Свойство EntityEntries вернет значение null, поскольку один объект не может быть идентифицирован как источник исключения. Обработка исключений при сохранении может упростить, предоставив свойства внешнего ключа в ваших типах сущностей. Подробнее см. InnerException.»}

И я получаю это как внутреннее исключение:

Оператор обновления, вставки или удаления хранилища затронул непредвиденное количество строк (0). Объекты могли быть изменены или удалены после загрузки объектов. См. http://go.microsoft.com/fwlink/?LinkId=472540. для получения информации о понимании и обработке исключений оптимистического параллелизма.

Я получаю это исключение, потому что все идентификаторы равны нулю? Или я что-то еще упускаю?

Еще одна вещь: в Entity есть поле int, я его не заполняю. Это источник исключения?

Спасибо.

В моем случае исключение было выбрано потому, что EF неправильно создал миграцию.
Он пропустил настройку identity: true во второй таблице. Поэтому перейдите в миграцию, которая создала соответствующие таблицы, и проверьте, не было ли упущено ее добавления.

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);

Столбец Id должен иметь идентификатор (т.е. автоматически увеличивать!), поэтому это должна быть ошибка EF.

Вы можете добавить личность вручную с SQL непосредственно в базу данных, но я предпочитаю использовать Entity Framework.

Если вы столкнулись с той же проблемой, я вижу два простых решения:

Alt 1

измените неверно созданную миграцию с помощью

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

Затем добавьте идентификатор: true вручную в код миграции, а затем обновите базу данных снова.

Alt 2

создается новая миграция, которая добавляет идентификатор. Если у вас нет изменений в моделях, и вы запустите

add-migration identity_fix

он создаст пустую миграцию. Затем просто добавьте этот

    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));
        }
    }

Я пытаюсь разработать следующие отношения сущностей

  • Программа
  • сборка

Программа может иметь несколько сборок. Одна из сборок будет основной сборкой. Каждая сборка принадлежит только одной программе.

Классы моделируются следующим образом:

public class Program
{
    public int Id {get;set;}
    public virtual ProgramAssembly MainAssembly {get;set;}
    public virtual ICollection<ProgramAssembly> Assemblies {get;set;}
}

public class ProgramAssembly
{
   public int Id {get;set;}
   public virtual Program Program {get;set;}
   public int ProgramId {get;set;}
}

Я ничего не указываю с помощью FluentApi (однако я ничего против этого не имею).
В приведенном выше коде я получаю эту ошибку:

Произошла ошибка при сохранении сущностей, которые не предоставляют свойства внешнего ключа для своих связей. Свойство EntityEntries вернет значение null, поскольку один объект не может быть идентифицирован как источник исключения. Обработку исключений при сохранении можно упростить, предоставив свойства внешнего ключа в ваших типах сущностей. Подробнее см. InnerException.

InnerException: невозможно определить допустимый порядок зависимых операций. Зависимости могут существовать из-за ограничений внешнего ключа, требований модели или значений, сгенерированных хранилищем.

Я попытался изменить ProgramAssembly на следующее

public class ProgramAssembly
{
    [ForeignKkey("Program")]
    public int Id {get;set;}
    public virtual Program Program {get;set;}
}

Однако затем я получаю эту ошибку:

ProgramAssembly_Program_Source: : Множественность недопустима в роли «ProgramAssembly_Program_Source» в отношении «ProgramAssembly_Program». Поскольку зависимая роль относится к ключевым свойствам, верхняя граница кратности зависимой роли должна быть равна «1».

Я также попробовал следующий свободный подход API

modelBuilder.Entity<ProgramAssembly>()
   .HasRequired(a => a.Program)
   .WithMany(p => p.Assemblies);

public class ProgramAssembly
    {        
        public int Id { get; set; }
        public virtual Program Program { get; set; }
        [ForeignKey("Program")] //same error with or without this attribute
        public int ProgramId { get; set; }
   }

Тогда ошибка:

Произошла ошибка при сохранении сущностей, которые не предоставляют свойства внешнего ключа для своих связей. Свойство EntityEntries вернет значение null, поскольку один объект не может быть идентифицирован как источник исключения. Обработку исключений при сохранении можно упростить, предоставив свойства внешнего ключа в ваших типах сущностей. Подробности смотрите в InnerException». UpdateException: невозможно определить допустимый порядок зависимых операций. Зависимости могут существовать из-за ограничений внешнего ключа, требований модели или значений, сгенерированных хранилищем.

Как разрешить эту связь без изменения подхода к добавлению атрибута IsPrimary в сборку?

Я видел несколько похожих вопросов на SO, но они были либо о ядре EF, например этот или предложенное существенное изменение логики, например этот или даже этот, который даже не компилируется.

При попытке вызвать SaveChanges() я получаю следующую ошибку:

Произошла ошибка при сохранении сущностей, которые не предоставляют свойства внешнего ключа для своих связей. Свойство EntityEntries вернет значение null, поскольку один объект не может быть идентифицирован как источник исключения. Обработку исключений при сохранении можно упростить, предоставив свойства внешнего ключа в ваших типах сущностей. Подробности смотрите в InnerException».

SqlException: недопустимое имя столбца «Artwork_Id»

Я использую Entity Framework.

Я пытаюсь добавить artworkImage с идентификатором произведения искусства в качестве ссылки. Вся информация передается корректно, но не сохраняется.

public partial class ArtworkImage
{
    [Key]
    public int Id { get; set; }
    public string ImageURL { get; set; }
    public Artwork Artwork { get; set; }
}

public partial class Artwork
{
    [Key]
    public int Id { get; set; }
    public string Category { get; set; }
    public ICollection<ArtworkImage> ArtworkImage { get; set; }
}

Мой DbContext:

public DbContext()
        : base("name=DbConnection")
    {
        this.Configuration.AutoDetectChangesEnabled = false;
    }

    public virtual DbSet<Artwork> Artworks { get; set; }

    public virtual DbSet<ArtworkImage> ArtworkImages { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Artwork>()
            .Property(e => e.Category)
            .IsFixedLength();

        Database.SetInitializer<DbContext>(null);
        base.OnModelCreating(modelBuilder);
    }

Если какой-либо информации не хватает, укажите ее, и я добавлю ее.

2 ответа

Вы должны объявить первичный ключ для каждой таблицы. это редкий случай, когда таблица не имеет PK. почти никогда.

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


0

Boppity Bop
2 Сен 2022 в 17:25

Таким образом, часть вашей проблемы может заключаться в том, что вы не определяете отношение в обратном порядке, что, я считаю, важно для того, как оно устанавливает, является ли отношение один к одному или один ко многим. Поэтому вам, вероятно, потребуется добавить в класс Artwork свойство типа ArtworkImage (если оно взаимно однозначное). если это один ко многим, вам нужно будет сделать свойство некоторой общей коллекцией с общим типом ArtworkImage.

Один к одному

public partial class Artwork
{
    [Key]
    public int Id { get; set; }
    public string Category { get; set; }
    public ArtworkImage ArtworkImage { get; set; }
}

Один ко многим

public partial class Artwork
{
    [Key]
    public int Id { get; set; }
    public string Category { get; set; }
    public IEnumerable<ArtworkImage> ArtworkImages { get; set; }
}


0

MarkieMark
2 Сен 2022 в 18:21

  • Ошибка при стирке атлант f4
  • Ошибка при сохранении статуса формы яндекс маркет
  • Ошибка при стирке he2
  • Ошибка при сохранении профиля беспроводной связи windows 7
  • Ошибка при стирке h2o