#c# #sql-server #entity-framework #ef-code-first
#c# #sql-сервер #сущность-фреймворк #ef-код-первый
Вопрос:
Допустим, у меня есть класс под названием Expense
. Я могу добавить различные виды расходов, связанных с автомобилем — расходы на заправку, расходы на ремонт, билеты и т.д. Некоторые свойства расхода одинаковы для всех типов, таких как стоимость, дата и т.д., Но есть некоторые различия. Например: когда я заправляю свой автомобиль, я хочу сохранить информацию, например, полностью ли я заправил свой бак или нет. Однако, когда я сохраняю восстановление, я хочу сохранить некоторую другую информацию.
Проблема в том, как создать какой-то механизм гибких свойств?
То , что я придумал , — это иметь две таблицы: expenses
и expenses_properties
. В expenses
таблице я мог бы хранить все основные, общие данные и expenses_properties
имел бы следующую структуру:
| Id | PropertyName | PropertyValue | ExpenseId
| 1 | IsFull | "true" | 1
| 2 | Stuff | "2016-10-02" | 1
Проблема в том, что для PropertyValue
столбца мне пришлось бы использовать определенный тип, например nvarchar
, например. В этом случае я не смог бы правильно отсортировать эти значения (например, по дате)? Или, может быть, я бы так и сделал?
Я думаю, что должен быть лучший способ сделать это, используя подход Entity Framework Code First.
Комментарии:
1. Если вы знаете официальный термин для этого — значение атрибута сущности , вы можете провести некоторые дальнейшие исследования. Я уверен, что это заставит вас дважды подумать.
2. @Герт, большое тебе спасибо! Исследование действительно заставило меня дважды подумать!
Ответ №1:
Я бы сначала создал вашу модель класса / объекта (а не наоборот, т. Е. Начиная с базы данных):
public abstract class ExpenseBase
{
public DateTime ExpenseDate { get; set; }
public double Cost { get; set; }
}
public class FuelExpense : ExpenseBase
{
public Boolean FilledUp { get; set; }
}
public class OtherExpense : ExpenseBase
{
public string SomeOtherProperty { get; set; }
}
Затем выберите стратегию сопоставления наследования. В этой ситуации я обычно использую «Таблицу для каждого конкретного класса» (TPC).
Ответ №2:
Если существуют разные типы расходов, то на самом деле имеет смысл иметь разные классы (т.Е. Разные таблицы). У вас может быть Expenses
место, где вы можете хранить общие данные, а затем TankExpense
место, где вы храните определенные «свойства» со столбцом ExpenseId
, который может быть внешним ключом идентификаторов таблицы расходов. Когда вам нужно получить экземпляр expense, вы просто извлекаете if с помощью EF, и появятся все связанные с этим расходы:
if (myExpense.TankExpense.Length > 0)
{
var isFull = myExpense.TankExpense[0].Full;
}