EF Core отношения без внешнего ключа - PullRequest
2 голосов
/ 06 апреля 2020

Как настроить свойство навигации без объявления внешнего ключа?

У меня есть две таблицы (segment и category), они могут объединяться с использованием 2 столбцов (источник / место назначения), но они не соответствуют ограничению внешнего ключа, поскольку могут иметь значение, которое не соответствует существует в другой таблице (поэтому она не равна нулю или не равна нулю)

Сегмент

Id   Date       OriginId  DestinationId
---------------------------------------
1    2020-01-10    1        2
2    2020-01-18    2        1
2    2020-02-05    1        3
4    2020-04-11    3        3

Категория

Id  OriginId   DestinationId  Category
-----------------------------------------
1      1            2         Primary
2      2            1         Secondary
2      2            3         Primary

Я хочу знать каждую Segment категорию. Но не каждый сегмент существует в Category, поэтому некоторые сегменты не будут иметь категории.

Это SQL работает:

SELECT 
    s.*, c.name
FROM 
    Segment s
LEFT OUTER JOIN 
    Category c ON c.originId = s.originId AND c.destinationId = s.destinationId

Этот LINQ также работает:

from s in Segment
join c in Category on new { s.OriginId, s.DestinationId } equals new { c.OriginId, c.DestinationId } into grouping
from c in grouping.DefaultIfEmpty()
select new { s, c };

Но для использования навигации, самое близкое, что я получил, это: я добавил свойство для каждого класса соответственно и установил отношения в контексте, используя свободный API

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Segment>()
        .HasOne(segment => segment.Category)
        .WithMany(category => category.Segments)
        .HasForeignKey(segment => new { segment.OriginId, segment.DestinationId })
        .HasPrincipalKey(category => new { category.OriginId, category.DestinationId })
        .IsRequired(false);
}

// then I can do
var query = Segments.Include(o => o.Category).ToList();

. Это работает для извлечения записей, которые уже существуют в база данных.

Но для вставки новой записи в Сегмент, где originId и destinationId не существует в Category, он жалуется на originId и destinationId, не удовлетворяющие ограничению внешнего ключа. И это нормально, потому что они не существуют в другой таблице.

Они на самом деле не являются внешними ключами, а просто столбцом, который можно использовать для их объединения, но я не знаю, как установить это с помощью свойства навигации + Свободный Api.

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