Моделирование родовых отношений (выраженных в C #) в базе данных - PullRequest
1 голос
/ 30 марта 2010

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

Как мне эффективно моделировать реляционную базу данных, в которой у меня есть поле в таблице «Событие», которое определяет «SportType»?

Это поле "SportsType" может содержать ссылку на различные спортивные таблицы. "FootballEvent", "RubgyEvent", "CricketEvent" и "Событие F1".

Каждый из этих спортивных столов имеет различные поля, специфичные для этого вида спорта .

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

Можно ли использовать ORM, такой как NHibernate / Entity framework / DataObjects.NET, который бы отражал такие отношения?

Я собрал быстрый пример C #, чтобы выразить свое намерение на более высоком уровне:

public class Event<T> where T : new()
{
    public T Fields { get; set; }

    public Event()
    {
        EventType = new T();
    }
}

public class FootballEvent
{
    public Team CompetitorA { get; set; }  
    public Team CompetitorB { get; set; }    
}

public class TennisEvent
{
    public Player CompetitorA { get; set; }
    public Player CompetitorB { get; set; }
}

public class F1RacingEvent
{
    public List<Player> Drivers { get; set; }
    public List<Team> Teams { get; set; }
}

public class Team
{
    public IEnumerable<Player> Squad { get; set; }
}

public class Player
{
    public string Name { get; set; }
    public DateTime DOB { get; set;}
}

football Event code completion f1 Event code completion

Ответы [ 4 ]

3 голосов
/ 30 марта 2010

DataObjects.Net поддерживает автоматические сопоставления для открытых обобщенных элементов. Некоторые подробности об этом описаны здесь .

2 голосов
/ 02 апреля 2010

Пример, преобразованный в DO4, должен выглядеть следующим образом:

// I'd add this type - adding an abstract base makes design more clean + allows you to share
// the behavior among all the descendants
[Serializable]
[HierarchyRoot]
public abstract class EventBase : Entity
{
  [Key]
  Guid Id { get; private set; } // Or some other type
}

[Serializable]
public class Event<T> : EventBase
    where T : IEntity, new() // IEntity indicates DO4 must try  to map its descendants automatically
    // Although I'd put some stronger requirement, e.g. by using IEventData instead of IEntity here
{
    public T Data { get; set; }

    public Event(T data)
    {
        Data = data;
    }
}

[Serializable]
[HierarchyRoot]
public class FootballEvent
{
    // You need [Key]  here
    public Team CompetitorA { get; set; } 
    public Team CompetitorB { get; set; }   
}

[Serializable]
[HierarchyRoot]
public class TennisEvent
{
    // You need [Key]  here
    public Player CompetitorA { get; set; }
    public Player CompetitorB { get; set; }
}

[Serializable]
[HierarchyRoot]
public class F1RacingEvent
{
    // You need [Key]  here
    public EntitySet<Player> Drivers { get; private set; }
    public EntitySet<Team> Teams { get; private set; }
}

[Serializable]
[HierarchyRoot]
public class Team
{
    // You need [Key]  here
    public EntitySet<Player> Squad { get; set; }
}

[Serializable]
[HierarchyRoot]
public class Player
{
    public string Name { get; set; }
    public DateTime DOB { get; set; }
}

В этом случае экземпляры событий будут доступны (= сопоставлены автоматически) для всех подходящих Ts из модели. Например. в этом случае они будут: - EventBase // Да, даже это, потому что это подходит - FootballEvent - TennisEvent - F1RacingEvent - Команда - Игрок

Если вы хотите ограничить это только определенными типами, вы должны сделать следующее: - Добавить интерфейс, унаследованный от IEntity, который будут поддерживать все эти типы, например IEventData. - Используйте его как ограничение общего параметра для общего параметра T в событии.

Крест Опубликовано: http://forum.x -tensive.com / viewtopic.php? F = 29 & t = 5820 , Ответить Алекс Якунин , Генеральный директор DataObjects.NET

2 голосов
/ 30 марта 2010

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

0 голосов
/ 30 марта 2010

Существует множество параметров, таких как столбцы XML и EAV (также называемые базой данных в базе данных), но ни один из них не будет хорошо преобразовываться с ORM в традиционные статические объектно-ориентированные языки, и все они имеют недостатки в отношении безопасности типов данных и ссылочной целостности на уровне базы данных.

Если вам нужен такой уровень динамической структуры как в базе данных, так и в клиенте, вам может потребоваться использовать базу данных объектов или документов (и язык), которая является гораздо более динамичной по своему дизайну - реляционные базы данных лучше всего работают со статической отношения и модели данных.

...