Entity Framework - Избегание дочерних дубликатов, если они еще не сохранены - PullRequest
0 голосов
/ 22 июля 2011

На самом деле я использую DbContext, но я только что проверил его и с ObjectContext.

// Engine 1
Engine engine = new Engine();
Manufacturer manufacturer = new Manufacturer();

engine.Manufacturer = manufacturer;

// Engine 2
engine = new Engine();
engine.Manufacturer = manufacturer // Engine 2 has the same manufacturer like Engine 1

context.SaveChanges();

Я использую столбцы идентификаторов (int), где генерируются новые идентификаторы.В режиме отладки я вижу, что идентификатор для двигателя "0".Хорошо, если я реализую context.SaveChanges сразу после блока Engine 1, новый производитель сохраняется в БД.С EntityKey или Любой проверкой я могу без проблем ссылаться на нового производителя на Engine 2.Но без немедленной SaveChanges () две записи одного производителя сохраняются в БД (код выше).EF не может ссылаться внутренне, как нормальные объекты?Как вы видите выше, производитель - это один и тот же объект, поэтому мне интересно, возможно ли получить успешную вставку без предварительного сохранения дочернего элемента / производителя.

РЕДАКТИРОВАТЬ: Я думаю, что нашел проблему

MachineEntities context = new MachineEntities();
        context.Configuration.AutoDetectChangesEnabled = true;

        // Engine 1
        Engine engine1 = new Engine();
        engine1.Name = "engine1";

        Manufacturer manufacturer = new Manufacturer();
        manufacturer.Name = "manufacturer1";

        engine1.Manufacturer = manufacturer;

        // Engine 2
        Engine engine2 = new Engine();
        engine2.Name = "engine2";

        manufacturer = new Manufacturer();
        manufacturer.Name = "manufacturer1";

        engine2.Manufacturer = manufacturer;


        // Add Engine 1

        if (context.Manufacturers.Any(m => m.Name == engine1.Manufacturer.Name))
        {
            // The manufacturer's name is identical, so use the one in the context instead the assigned one.
            engine1.Manufacturer = context.Manufacturers.Single(m => m.Name == engine1.Manufacturer.Name);
        }
        else
        {
            // The manufacturer is not known, add it to the context
            context.Set<Manufacturer>().Add(engine1.Manufacturer);
        }

        // Add Engine 2


        if (context.Manufacturers.Any(m => m.Name == engine1.Manufacturer.Name))
        {
            // The manufacturer's name is identical, so use the one in the context instead the assigned one.
            engine2.Manufacturer = context.Manufacturers.Single(m => m.Name == engine2.Manufacturer.Name);
        }
        else
        {
            context.Manufacturers.Add(engine2.Manufacturer);
        }

        context.SaveChanges();

        context.Dispose();

«Любое» или любое сравнение не даст мне никаких результатов.Это дает мне только те сущности, которые уже сохранены в БД, но не новые новые добавленные.Так что это дублируется.Локальные из них игнорируются, как я вижу в отладчике, а те, что в «Result View», являются теми, против которых выполняется команда.Таким образом, новые добавленные объекты находятся в "Manufacturers.Local".

1 Ответ

1 голос
/ 22 июля 2011

Я только что попробовал следующее:

var a1 = new Activity{WorkflowId = 1, Title = "test"};
var a2 = new Activity{WorkflowId = 1, Title = "test2"};
var d = new WorkflowDisplay{WorkflowId = 1, Title = "Test"};
a1.WorkflowDisplay = d;
a2.WorkflowDisplay = d;
// Any of the next three lines can be commented out, but if
// they are all commented, nothing happens.
AddToWorkflowDisplays(d);
AddToActivities(a1);
AddToActivities(a2);
SaveChanges();

... и я видел только один добавленный WorkflowDisplay. Так что я уверен, что это как-то связано с вашей конкретной реализацией. Переопределяли ли вы методы GetHashCode или Equals какой-либо из ваших сущностей или выполняли какую-либо аналогичную настройку автоматически сгенерированного кода?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...