Разработка Entity Framework совместимой модели данных - PullRequest
0 голосов
/ 01 марта 2019

Я пытаюсь разработать модель данных для приложения c # .net Core с использованием Entity Framework Code.

То, что я в основном имею, это модель данных ниже.

enter image description here

Есть таблицы Dog и Person.Каждый из них содержит различную информацию.Например, у меня могут быть разные типы собак.Человек может иметь что-то конкретное, и это не относится к собакам.

Существует соотношение 1: 1 между Person и Item.Такое же соотношение между Dog и Item.

В дополнение к этой таблице ItemReference содержит дочерние и родительские отношения между Предметами.Например, между собакой и человеком есть родительские отношения (владелец собаки - собака или люди могут быть братьями и сестрами)

Мне нужно составить алфавитный список собак и людей (перепутать их). Кроме того, мне нужнобыть в состоянии перейти на страницу деталей для каждого из следующих.

Использовать это действительно глупо, так как в будущем может появиться больше таблиц.Например, Cat или Car, и мне нужно каждый раз переделывать эти операторы If.

@foreach (var x in Model.Item.OrderBy(y=>y.ItemName))
{
    if (x.ItenType == "Dog")
    {
        <li><a asp-page="DogDetails" asp-route-id="@x.Item.Dog.Id">@x.ItemName</a></li>
    }
    if (x.ItenType == "Person")
    {
        <li><a asp-page="PersonDetails" asp-route-id="@x.Item.Person.Id">@x.ItemName</a></li>
    }
}

Кто-нибудь знает, как сделать такую ​​модель данных, чтобы она была более разумной?

Любая помощь с благодарностью

Таблицы Dog, Person и Item будут выглядеть так:

Dog

Id  DogName     DogTypeId   DogStatusId ItemId
1   "Alex"      1           1           1
2   "Rex"       2           1           2

Человек

Id  PersonName  PersonStatusId      ItemId
1   "Joe"       1                   3     
2   "Jane"      2                   4

Элемент

Id  ObjectName   ItemType
1   "Alex"       "Dog"
2   "Rex"        "Dog"
3   "Joe"        "Person"
4   "Jane"       "Person"

1 Ответ

0 голосов
/ 01 марта 2019

Ваш объектный график не совсем понятен.Похоже, Dog и Person просто связаны с Item, но на основании вашего описания и краткого примера кода может показаться, что они на самом деле типы элементов.Если это так, вы должны использовать стратегию наследования, а не композицию.

public class Item

public class Dog : Item

public class Person : Item

По умолчанию EF будет обрабатывать наследование с помощью стратегии TPH (таблица на иерархию), которая здесь не подходит.Вместо этого я думаю, что вам понадобится TPT (таблица для каждого типа), что может быть достигнуто с помощью атрибута Table в производном классе:

[Table("Dogs")]
public class Dog : Item

[Table("Persons")]
public class Person : 

Что это будет делать, это создать три таблицы,Dogs, Persons и Items.Любые данные, общие для всех предметов, независимо от того, собака это или человек, очевидно, попадут в ваш класс Item и окажутся в таблице Items.Внешние ключи будут добавлены в таблицу Dogs и Persons, указывая на таблицу Items.Например, когда вы извлекаете Dog, EF автоматически присоединяется к соответствующей записи в Items для создания полного Dog.

. Это дает вам некоторые особые возможности в ваших запросах.Вы можете получить все элементы независимо от их типа, конечно же, с помощью _context.Items, но вы также можете иметь отдельные DbSet для Dog и Person, что позволит вам запрашивать их независимо: например, _context.Dogs.Даже без явного DbSet вы можете использовать общий метод Set<TEntity>: _context.Set<Dog>().Кроме того, вы можете использовать OfType<TEntity> для фильтрации набора Items: _context.Items.OfType<Dog>().

Наконец, даже если вы просто извлекаете Items, EF по-прежнему отслеживает, какой конечный тип у каждого Item, какойозначает, что вы можете делать такие вещи, как сопоставление с образцом:

if (item is Dog dog)
{
    // `dog` is now a variable in this scope of your `item` downcast to `Dog`
}

Или в операторах switch:

switch (item) 
{
    case Dog dog:
        // do something with `dog`
        break;
    case Person person:
        // do something `person`
        break;
    default:
        // do something with generic items (`item`)
        break;
}

EDIT

Я понял, что только яссылался на следующее, а не заявляя явно.Поскольку Dog и Person - это совершенно разные таблицы в TPT, вы можете определить там совершенно разные отношения.Например, Dog может иметь отношение с DogStatus, не затрагивая ничего, что происходит с Person.Технически вы все еще можете сделать это даже с TPH, но в итоге у вас будет куча внешних ключей, которые можно обнулять, в таблице Items, и это будет просто беспорядок, а также нарушит нормализацию.

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