Как сохранить или правильно привести объект к типу? - PullRequest
0 голосов
/ 10 января 2019

Я занимаюсь этой проблемой.

У меня есть базовый класс Worker, который является абстрактным. Его базовый класс для Driver и AmountBonus. Это Bonus написано на основе шаблона оформления Decorator . Мой декоратор украсит одно из имущества от Worker.

Как это выглядит в коде:

public abstract class Worker {}

public class Driver : Worker {}

public abstract class Bonus : Worker 
{
    public Bonus(Worker worker) => this.worker = worker; //constructor
    //decorator on worker's property
}

public class AmountBonus : Bonus 
{
     public AmountBonus(Worker worker) : base(worker: worker){ } //constructor
}

Я делаю WebApi приложение. Я оперирую данными по конечным точкам. Это моя PUT просьба:

    // PUT: api/Bonus/Amount/5
    [HttpPut("Amount/{id}")]
    public Worker Get(int id)
    {
        var worker = _context.Workers.Find(id);

        switch (worker)
        {
            case Driver d:
                worker = new AmountBonus(worker) { Id = id };
                //exception here
                _context.Entry((Driver)worker).State = EntityState.Modified;
                _context.SaveChanges();
                break;
        }
        return worker;
    }

Это очевидно, что я получаю:

System.InvalidCastException: 'Невозможно привести объект типа' .... Models.Bonus.AmountBonus ', чтобы ввести' ... Models.Driver '.'

Но у меня вопрос, есть ли какие-то возможности для такого Driver типа объекта? Мне нужно было редактировать точно такую ​​же строку в моей базе данных. В моем столбце dbo.Workers есть столбец Discriminator, созданный Entity Framework Core, и мне нужно иметь такие значения, как Driver, Farmer и т. Д., Которые я создал и не упомянул в этом примере.

Я мог бы создать сущность для моего AmountBonus, что я сказал, мне нужно иметь тип объекта источника в моей базе данных. И мне нужно использовать Decorator там. Любые идеи, как я могу это сделать? Возможно ли сохранить происхождение Type?

Ответы [ 2 ]

0 голосов
/ 10 января 2019

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

[HttpPut("Amount/{id}")]
public Worker Get(int id)
{
    var worker = _context.Workers.Find(id);

    switch (worker)
    {
        case Driver d:
            var amountBonus = new AmountBonus(worker) { Id = id };
            amountBonus.ExecuteDecoration();

            _context.Entry(worker).State = EntityState.Modified;
            _context.SaveChanges();
            break;
    }

    return Ok(worker);
}

AmountBonus класс даже не должен наследовать от Worker. Ваша проблема с кастингом исчезнет сама собой
Тогда это больше похоже на шаблон посетителя;)

0 голосов
/ 10 января 2019

То, что вы делаете, не имеет смысла. Декораторы - это служебные классы; они накладывают программную функциональность на классы, которые они украшают. Они не являются чем-то, что не может и не должно сохраняться в чем-то вроде базы данных.

Другими словами, если ваш объект - Driver, то вам нужно сохранить его Driver, а не оборачивать его в AmountBonus декораторе, а затем попытаться сохранить , что . Позже, если вам понадобятся какие-либо функции, добавленные декоратором AmountBonus, вы просто снова включите в него свой экземпляр Driver.

Это даже не похоже на то, что вы делаете что-то интересное с декоратором здесь, но если есть что-то, что происходит просто в результате обёртывания экземпляра Driver, то вам нужно как-то извлечь это затем обернутый экземпляр Driver для фактического сохранения этого , а не вашего декоратора.

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