Создаю ли я модели из моделей инфраструктуры сущностей или отредактирую модели инфраструктуры сущностей и использую их в MVVM? - PullRequest
0 голосов
/ 24 февраля 2019

Я некоторое время искал прямой ответ, но, похоже, не могу его найти.

Я пытаюсь изучить шаблон MVVM в WPF, и мне было интересно, являются ли мои модели сущностьюФреймворк создает или, если мне нужно создать модели, которые в основном являются копиями моделей фреймворков сущностей.

Например, моя модель фреймворка сущностей для моих самых базовых tblMyEmployees выглядит следующим образом

    public partial class tblMyEmployee
{
    public int pkEmployee { get; set; }
    public string strFirstName { get; set; }
    public string strLastName { get; set; }
}

Так что я долженсоздайте модель, в основном копируя и вставляя свойства из сгенерированной модели платформы сущностей, и реализуйте INotifyPropertyChanged, используя мой BaseViewModel, а также любые другие свойства, которые я мог бы счесть полезными, например:

class EmployeeModel: BaseViewModel
{
    public int pkEmployee { get; set; }
    private string _strFirstName;
    public string strFirstName
    {
        get { return _strFirstName; }
        set
        {
            _strFirstName = value;
            SetProperty(ref _strFirstName, value);
        }
    }
    private string _strLastName;
    public string strLastName
    {
        get { return _strLastName; }
        set
        {
            _strLastName = value;
            SetProperty(ref _strLastName, value);
        }
    }
    private string _strFullName;
    public string strFullName
    {
        get { return strFirstName + " " + strLastName; }
    }
}

Или я должен добавить свои дополнительные свойстваи вместо этого реализовать INotifyPropertyChanged для сгенерированной модели?

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

Комментарий вверху сгенерированногомодель заставляет меня задуматься, стоит ли мне создавать собственные модели на ее основе

// Этот код был сгенерирован из шаблона.

// Ручные изменения этого файла могут вызвать непредвиденное поведение в вашем приложении.

// Ручные изменения в этом файле будут перезаписаны при повторном создании кода.

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Как отметил Марк Фельдман в этом ответе https://stackoverflow.com/a/54856785/249665,, есть несколько способов сделать это.

В большинстве случаев модели представления и доменные сущности (модели) различаются;они будут идентичны только в действительно простом приложении CRUD.

Например, модель представления может содержать подмножество свойств модели или свойств нескольких моделей.

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

Кроме того, у viewmodel могут быть такие вещи, как списки для комбинированных окон и т. д., и значения для них могут быть получены из других моделей (объектов-значений).

Вот мой нынешний подход (используя NHibernate, у меня, к сожалению, очень мало опыта в EF, но я думаю, что на этом уровне нет различий).

  1. Доменные сущности должныне реализован INPC
  2. Избегайте излишней логики в моделях представления
  3. Выделите код для загрузки представлений в отдельные классы.
  4. Разложите код для выполнения обновлений для отдельных классов.
  5. Проверьте данные для 3 и 4 с помощью FluentValidation.

Для 3 и 4 выше посмотрите на https://jimmybogard.com/vertical-slice-architecture/

В итоге вы можете получить такие классы:* Модель сотрудника * Создание новой модели представления сотрудника * Редактирование модели представления зарплаты * Запрос GetNewEmployee (этот будет получать все данные, необходимые для созданияввод нового сотрудника, такого как список отделов, должностей и т. д.) * Команда SaveNewEmployee (сохраняется новый сотрудник) * Запрос зарплаты GetEmployee (этот может проверять, разрешено ли пользователю просматривать, но не изменять зарплату, возможно, он получает мин.максимальная зарплата, типы зарплаты и т. д.) * Команда UpdateSalary * Проверка нового сотрудника * Проверка зарплаты

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

0 голосов
/ 25 февраля 2019

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

  1. Для каждого из ваших классов моделей создайте соответствующую модель представления.
  2. Используйте PropertyChange.Fody , чтобы добавить INPC для вас во время компиляции.
  3. Используйте что-то вроде Castle DynamicProxy для внедрения INPC во время выполнения (однако при этом необходимо учитывать некоторые важные проблемы, так как ваш ORM должен предоставлять возможность проксировать оба объекта модели, которые он создаети особенно любые коллекции).
  4. Делать INPC вручную.Скорее всего, изменения в ваших моделях всегда исходят из представления, и в этом случае INPC фактически не требуется.В этом случае единственными изменениями, которые необходимо распространять в обратном направлении, являются добавления и удаления коллекций, в этом случае вы оставляете их как обычные списки (скажем) и вызываете событие изменения INPC вручную при каждом изменении списка.(Это немного уродливое решение, и могут быть проблемы с производительностью, но это возможно).

Какой из них я использую сам, зависит от проекта.Я использовал # 3, но он настолько тесно связан с ORM, что больше не является моим предпочтительным вариантом.Для работы с Xamarin я склонен использовать # 2, но для большинства вещей WPF я склонен использовать модели представлений для управления коллекциями, но, по возможности, привязываться напрямую к свойствам моделей.Поначалу кажется, что возможность привязки нескольких частей вашего представления к одной и той же модели представления привлекательна до тех пор, пока вы не поймете, что это создает более запутанный интерфейс и мешает любому виду функций отмены / отмены, которые могут ожидать ваши пользователи.

ОБНОВЛЕНИЕ: если вы пойдете по пути объявления всех свойств вашей модели явным образом, то вы будете снова и снова писать один и тот же код.Я экономлю много времени, помещая эту функциональность в фрагмент кода:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>propc</Title>
            <Shortcut>propc</Shortcut>
            <Description>Code snippet for an automatically implemented change notification property</Description>
            <Author>Mark Feldman</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal>
                    <ID>type</ID>
                    <ToolTip>Property type</ToolTip>
                    <Default>int</Default>
                </Literal>
                <Literal>
                    <ID>property</ID>
                    <ToolTip>Property name</ToolTip>
                    <Default>MyProperty</Default>
                </Literal>
            </Declarations>
            <Code Language="csharp"><![CDATA[private $type$ _$property$;
    public $type$ $property$
    {
        get { return this._$property$;}
        set
        {
            if (this._$property$ != value)
            {
                this._$property$ = value;
                RaisePropertyChanged(() => this.$property$);
            }
        }
    }
    $end$]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

Импортируйте это через Tools-> Code Snippets Manager, а затем введите «propc» в любом месте класса, за которым следуют 2 вкладки, которые будутсгенерируйте большую часть стандартного кода для свойства INPC с внутренним полем и позвольте заменить тип и имя:

private string _MyText;
public string MyText
{
    get { return this._MyText; }
    set
    {
        if (this._MyText != value)
        {
            this._MyText = value;
            RaisePropertyChanged(() => this.MyText);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...