Как связать два навигационных свойства разных моделей с одним столбцом с внешним Id EFCore
Использую VS2022, EF Core 6, SQLite, Code First.
Представлен пример механизма хранения хода событий в большой системе.
Имеется следующие модели:
public class EntityBase
{
public int CreateEventId { get; set; }
public virtual Event CreateEvent { get; set; }
}
public class User : EntityBase
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Clip : EntityBase
{
public int Id { get; set; }
public string Name { get; set; }
public int EventId { get; set; }
public virtual Event Event { get; set; }
// другие свойства
}
public class Clip
{
CreateUser = 10,
ModifyUser = 11,
DeleteUser = 12,
CreateClip = 20,
ModifyClip = 21,
DeleteClip = 22,
}
public class Event
{
public int Id { get; set; }
public EventType Type { get; set; }
public EventTime { get; set; }
public int UserId { get; set; }
public virtual User User { get; set; }
// интересующие свойства
public int ObjectId { get; set; }
public virtual User { get; set; } // если EventType = 10..19 то не null
public virtual Clip { get; set; } // если EventType = 20..29 то не null
}
Свойство Event.ObjectId хранит Id на объект с которым произошло событие т.е. либо Clip.Id либо User.Id, для определения что за Id служит свойство Event.EventType.
Если способ как-то указать EF Core, что если в свойстве такие-то значения, то нужно связать с ObjectId такую-то модель.
Рассматривал хранение в
EF Coreполиморфных моделей, но тогдаUserиClipдолжны быть унаследованы отEvent, что не допустимо.Можно отправить
SQLсвой скрипт, но если ли штатный способ вEF Coreэто реализовать?Знаю, что можно хранить в отдельных столбцах (вместо
ObjectIdхранитьUserIdиClipId) иEFбудет корректно все обрабатывать, но мне кажется, что это не лучший способ, так как есть возможность хранить оба Id, что семантически неверно.
Вот скрипт SQLite, который я использую для просмотра БД, отражающий то, что мне надо:
SELECT
DATETIME(Events.EventTime,'localtime') AS 'LocalTime',
(
CASE
WHEN Events.EventType = 10 THEN 'CreateUser'
WHEN Events.EventType = 11 THEN 'ModifyUser'
WHEN Events.EventType = 12 THEN 'DeleteUser'
WHEN Events.EventType = 20 THEN 'CreateClip '
WHEN Events.EventType = 21 THEN 'ModifyClip '
WHEN Events.EventType = 21 THEN 'DeleteClip'
END
) AS "EventType",
Events.ObjectId,
(
SELECT Users.Name FROM Users WHERE Events.EventType BETWEEN 10 AND 19 AND Users.Id = Events.ObjectId
UNION
SELECT Clips.Name FROM Clips WHERE Events.EventType BETWEEN 20AND 29 AND Clips.Id = Events.ObjectId
) AS 'Object',
Events.EventData
FROM Events