Внешний ключ на второй таблице должен совпадать с PK на первой.
Например, для простоты используйте Int для типа ключа.
Если у меня есть Person с PKID: 1, SyncDate: 2019-05-22
Затем я добавляю второй вариант: PK ID: 1, SyncDate: 2019-05-23
Если я иду, чтобы добавить«Тестовая» запись, на какую запись Person она будет ссылаться с идентификатором FK Person 1?Он будет ссылаться на обе записи, поэтому EF не может поддерживать ссылку «HasRequired», указывающую на одну запись Person.
Чтобы сослаться на один вариант Person ID 1, вашей тестовой записи потребуются как PersonId, так и SyncDate дляидентифицируйте запись:
public class Test
{
public Guid Id { get; set; }
public Guid PersonId { get; set; }
public DateTime SyncDate { get; set; }
public virtual Person Person { get; set; }
}
modelBuilder.Entity<Test>()
.HasRequired(t => t.Person)
.WithMany(p => p.Tests)
.HasForeignKey(t => new { t.PersonId, t.SyncDate });
Таблицы в базе данных не могут ссылаться друг на друга, основываясь на частичном FK, если не много к 1. Т.е.
Person
------
PK: PersonID
PersonComment
-----------
PK: PersonId
PK: CommentDate
В этом примере Человек может иметь многоPersonComments на основе ссылки PersonID, в то время как комментарий может быть преобразован обратно в Person через Person ID.Как FK.
В структуре таблицы, которая имеет:
Person
------
PK: PersonID
PK: Version
PersonComment
-------------
PK: PersonCommentID
PersonId
PersonId в PersonComment не может быть FK для Person, поскольку он не отражает PK для таблицы Person.Вы можете легально иметь эту структуру таблицы, но PersonId - это просто тупой, неограниченный столбец.Вы можете запросить все записи человека вручную, используя его, но вы получите все версии человека.Нет никаких ограничений и т. Д., Чтобы гарантировать, что идентификатор человека в комментарии совпадает с идентификатором в таблице Person.
Если вам не нужны версии Person, вы можете иметь тестовую сущность с PersonID, но EF не может связать это с сущностями Person, вам придется вручную загружать записи Person из контекста.
Когда дело касается цели, лежащей в основе структуры схемы, я бы предложил рассмотреть возможные альтернативы.,Например, если ваша цель - отслеживать версионные данные, я бы посоветовал посмотреть что-то вроде:
Person
PK: PersonId
** Person Fields
PersonHistory
PK: PersonHistoryId
FK: PersonId
VersionDate
** Person Fields
Test
PK: TestId
FK: PersonId (if applies to current person, or PersonHistoryId if a specific version)
Тогда «Персона» отображает личность в ее текущем состоянии, содержащую коллекцию, отражающую историю.Оттуда вы можете предотвратить изменение полей Person с помощью частных сеттеров и методов в стиле DDD, которые будут отвечать за составление новой записи истории на основе текущих данных Person перед обновлением значений Person.Таким образом, запись Person может быть исторической и сохранять свой идентификатор для связанных объектов.