Entity Framework DB-First — могу ли я наследовать от базовой модели, чтобы добавить свою функциональность?

#c# #entity-framework #ef-database-first

#c# #entity-framework #ef-database-first

Вопрос:

Я создаю простое приложение на C #. Одной из его функций является добавление счетов.

Для этой цели я создал две таблицы в своей базе данных — Invoice и InvoiceLine, и использовал Entity Framework, чтобы сопоставить их для себя. Мне нужно было добавить некоторую функциональность для класса InvoiceLine, но я знаю, что вам не следует редактировать код, созданный Entity Framework. Вместо этого я решил наследовать от класса, созданного EF, и добавить эту функциональность поверх этого класса.

Я сделал это, но теперь, когда я пытаюсь сохранить это в базе данных, я получаю сообщение об ошибке — ‘System.Исключение InvalidOperationException: ‘Не удалось найти сопоставление и метаданные для EntityType ‘InvoiceRegister.Модели.InvoiceLineModel’.

Мой вопрос — как это можно исправить? Кроме того, есть ли лучший способ достичь того, чего я хотел? Я хотел выполнить свой проект в MVVM, поэтому я хотел создать модель, а не выполнять функциональность в моей ViewModel.

Код:

Исходный класс (InvoiceLine):

 //------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Manual changes to this file may cause unexpected behavior in your application.
//     Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace InvoiceRegister.Models
{
    using System;
    using System.Collections.Generic;

    public partial class InvoiceLine
    {
        public int DocEntry { get; set; }
        public int LineId { get; set; }
        public int LineNum { get; set; }
        public string ItemName { get; set; }
        public double Amount { get; set; }
        public int TaxPrc { get; set; }
        public decimal NetAmnt { get; set; }
        public decimal TaxAmnt { get; set; }
        public decimal TotalAmnt { get; set; }
        public decimal Price { get; set; }

        public virtual Invoice Invoice { get; set; }
    }
}
  

Мой класс. Я хочу, чтобы она наследовалась от InvoiceLine:

 namespace InvoiceRegister.Models
{
    public class InvoiceLineModel : InvoiceLine, INotifyPropertyChanged
    {
        private double _amount;

        public new double Amount
        {
            get { return _amount; }
            set
            {
                _amount = value;
                OnPropertyChanged("Amount");
                OnPropertyChanged("NetAmnt");
                OnPropertyChanged("TaxAmnt");
                OnPropertyChanged("TotalAmnt");
            }
        }

        private decimal _price;

        public new decimal Price
        {
            get { return _price; }
            set
            {
                _price = value;
                OnPropertyChanged("Price");
                OnPropertyChanged("NetAmnt");
                OnPropertyChanged("TaxAmnt");
                OnPropertyChanged("TotalAmnt");
            }
        }

        private int _taxPrc;

        public new int TaxPrc
        {
            get { return _taxPrc; }
            set
            {
                _taxPrc = value;
                OnPropertyChanged("TaxPrc");
                OnPropertyChanged("TaxAmnt");
                OnPropertyChanged("TotalAmnt");
            }
        }


        public new decimal TaxAmnt
        {
            get
            {
                return NetAmnt* TaxPrc/100;
            }
        }


        public new decimal NetAmnt
        {
            get
            {
                return  (decimal)Amount * Price;
            }
        }

        public new decimal TotalAmnt
        {
            get {return NetAmnt   TaxAmnt; }
        }

        public InvoiceLineModel()
        {
            this.LineNum = InvoiceViewModel.getNextLineNum();
        }
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string name)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }
}
  

Ответ №1:

Вы можете сделать это в подходе code first, но не в базе данных first, поэтому, по сути, вам нужно сначала обновить базу данных. Вы используете подход, основанный на базе данных, поэтому вам нужны следующие шаги:

1) Добавьте новые поля в таблицу в вашем случае («InvoiceLine») непосредственно в базу данных

2) После добавления вы можете обновить сгенерированную EF модель, щелкнув правой кнопкой мыши и обновив модель

3) При обновлении вам нужно установить флажок таблицы. (Прикрепите изображение для вашей ссылки) введите описание изображения здесь

введите описание изображения здесь

4) После обновления модели EF у вас могут быть свойства, доступные в классе, созданном EF

Вспомогательный ресурс:https://entityframework.net/ef-database-first

Все сделано.

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

1. Извините, что отвечаю так поздно, но опубликованное вами решение не имеет смысла для моей проблемы. Я «решил» проблему, просто вставив свой код в код, созданный EF. Спасибо за попытку.

2. как вставить код в сгенерированный EF код? Сгенерированный EF код доступен только для чтения. Это тоже не имеет смысла. правильно? Если вы вставите это (каким-либо образом), оно будет потеряно при каждом обновлении вашей модели. И в будущем вам нужно обновить свою модель, верно?