Вставка и удаление сложной структуры

#c# #.net #entity-framework

#c# #.net #entity-framework

Вопрос:

У меня есть следующие классы, которые представляют таблицы:

 public class PriceDefinition
    {
        public virtual long Id{get;set;}
        public virtual IList<Rule> Rules{get; set;}
        public virtual IList<PriceDefinitionAddition> Additions{get; set;}
        public virtual IList<CustomerPrice> CustomersPrices { get; set; }

        public PriceDefinition() { }
}

public class Rule
{
    public virtual long PriceDefinitionId { get; set; }
    public virtual string FieldName { get; set; }
    public virtual string Values { get; set; }
    public virtual string Text { get; set; }

    public Rule() { }
}

public class CustomerPrice
{
    public virtual long Id { get; set; }
    public virtual long CustomerId { get; set; }
    public virtual long PriceDefinitionId { get; set; }
    public virtual long TaskPriceId { get; set; }
    public virtual Price TaskPrice { get; set; }
    public virtual IList<CustomerAdditionPrice> AdditionsPrices { get; set; }

    public CustomerPrice() { }
}

public class CustomerAdditionPrice
{
    public virtual long CustomerPriceId { get; set; }
    public virtual long AdditionId { get; set; }
    public virtual long PriceId { get; set; }
    public virtual Price Price { get; set; }

    public CustomerAdditionPrice() { }
}

public class Price
{
    public virtual long Id { get; set; }
    public virtual decimal PriceSum { get; set; }
    public virtual decimal PricePercent { get; set; }
    public virtual long? UnitTypeId { get; set; }
    public virtual UnitTypeWrapper UnitTypeWrapper { get; set; }
    public UnitTypeEnum UnitType { get { return UnitTypeWrapper; } }

    public Price() { }
}

public class PriceDefinitionAddition
{
    public virtual long PriceDefinitionId { get; set; }
    public virtual long AdditionId { get; set; }

    public PriceDefinitionAddition() { }
}
  

У меня есть идентификатор PriceDefinition, и я должен удалить все связанные данные. Должен ли я повторять всю эту сложную структуру? Как я могу использовать include, а затем загрузить объект, чтобы загрузить всю структуру? Есть ли какой-нибудь простой способ удалить всю эту структуру?

У меня есть объект PriceDefinition, и я должен вставить в него все связанные с ним данные. Как я могу сделать это таким образом, чтобы при вызове SaveChanges все идентификаторы получали соответствующие значения? Должен ли я повторять все элементы, чтобы вставить их все?

Ответ №1:

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

Чтобы решить проблему вставки — подготовьте свой новый объект со всеми новыми связанными объектами и просто используйте AddObject для основного объекта. Также будут добавлены все связанные объекты, не отслеживаемые контекстом. Если ваши идентификаторы сгенерированы базой данных и правильно установлены с помощью StoreGeneratedPattern.Идентификация в вашем entity designer вам больше ничего не нужно делать.

Редактировать:

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

Комментарии:

1. @Ladislav Mrnka: Хорошо, итак, я должен удалять объекты один за другим (некоторые из объектов удаляются программно). Как я могу загрузить всю структуру (есть включение для дочерних объектов и внучатых объектов ..) Есть ли какая-нибудь «загрузка» или что-то в этомроде?

2. @Naor: Нет, не загружается все. Вы должны указать includes вручную для всей структуры.

3. @Ladislav Mrnka: Почему вы пишете «одно обращение к базе данных в оба конца для каждого удаления»? Не могу ли я использовать SaveChanges в конце процесса?

4. @Naor: Да, вы можете, но в EF нет пакетной обработки команд, поэтому он выполняет каждую команду как отдельный переход в БД — я уверен, что он делает это для Insert и Upadate, но я не проверял это для Delete. Я верю, что это будет то же самое. SaveChanges делает эти команды частью одной транзакции.

5. В моем случае я не хотел использовать каскадные удаления, потому что я не чувствовал, что это безопасно. (хотел уменьшить вероятность человеческой ошибки администратора базы данных, удаляющего запись, не осознавая, что это может вызвать многократные удаления). С другой стороны, я не хотел загружать все это с помощью EF, поэтому в итоге я запустил инструкцию delete sql для базы данных с контекстом. ExecuteStoreCommand