Почему «EntityKey не соответствует соответствующему значению в EntityKey»? - PullRequest
1 голос
/ 25 августа 2011

Сначала я хотел бы показать соответствующий фрагмент кода.Когда дело доходит до objCtx.AttachTo (), он выдает мне ошибку:

Error: "The object cannot be attached because the value of a property that is a part of the EntityKey does not match the corresponding value in the EntityKey."

        // convert string fragIds to Guid fragIds 
        var fragIdsGuids = docGenResult.FragIds.Select(c => new Guid(c)).ToList();

        //add each fragment to document))))
        foreach (Guid fragIdsGuid in fragIdsGuids)
        {
            var fragment = new Fragment() { EntityKey = new EntityKey("DocTestObjectContext.Fragments", "ID", fragIdsGuid) };
            objCtx.AttachTo("Fragments", fragment);
        }
        objCtx.SaveChanges();

Я проверил все и не пропускаю ни одного первичного ключа.

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

Я использую EF4 в среде C #.У меня есть много ко многим отношениям между двумя таблицами, Document и Fragments (первичный ключ "ID") (у документов может быть много фрагментов, а фрагмент может быть частью многих документов) Модель Entity прекрасно работает для меня.

Однако, когда я пытаюсь добавить новый документ в БД, у меня уже есть идентификаторы связанных фрагментов в моей руке.Для добавления нового документа в БД я должен вызвать каждый Fragmentobject и добавить его к сопоставленной ссылке в моем объекте документа.Это узкое место, поскольку документ может содержать более 1000 фрагментов.Следствием является то, что мне нужно 1 сек на документ.Немного, но мне нужно создать более 3000 документов, и сохранение этой секунды приведет к большей скорости.

Надеюсь, вы знаете, что здесь не так.

Спасибо.Томас

1-е редактирование:

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

        // convert string fragIds to Guid fragIds 
        var fragIdsGuids = docGenResult.FragIds.Select(c => new Guid(c)).ToList();
        // get responding entities from Fragment table
        var fragmentList = objCtx.Fragments.Where(c => fragIdsGuids.Contains(c.ID)).ToList();
        foreach (var fragment in fragmentList)
        {
            doc.Fragment.Add(fragment);
        }
        objCtx.SaveChanges();

2-е редактирование:

IТакое ощущение, что не совсем понятно, что я пытаюсь сделать.Однако я хотел бы связать / сослаться на существующие фрагменты в таблице фрагментов на основной документ в таблице документов.Документ, на который я хотел бы сослаться, является новым.Документ к таблице фрагментов имеет отношение многие ко многим.Это отношение имеет таблицу ссылок в базе данных.В модели это правильно смоделировано как отношение многих ко многим.Это нормально.

Пока все хорошо.Что работает, это то, что вы можете увидеть под моим первым редактированием.Я должен загрузить все необходимые фрагменты для документа по их идентификатору

// get responding entities from Fragment table
    var fragmentList = objCtx.Fragments.Where(c => fragIdsGuids.Contains(c.ID)).ToList();

После этого я могу добавить их к своему объекту документа:

foreach (var fragment in fragmentList)
    {
        doc.Fragment.Add(fragment);
    }

Но какого чертаНужно ли загружать всю сущность (фрагменты) только для того, чтобы связать ее с новым документом.Почему бы не сказать EntityStateManager «Чувак, у вас есть несколько фрагментов, свяжите их!»?

Далее я попытался следовать статье MSDN, упомянутой Адрианом в комментариях.Это не сработало для меня.

1 Ответ

0 голосов
/ 25 августа 2011

Я попробую это:

    var fragment = new Fragment {ID = fragIdsGuid};
    //fragment.EntityKey.Dump(); // -- this should be null
    objCtx.AttachTo("Fragments", fragment);
   //fragment.EntityKey.Dump(); // -- shows the EntityKey object, created after the object is attached

Функция дампа от LinqPad

...