В настоящее время я занимаюсь уборкой довольно большой базы данных. Часть базы данных имеет отношение, которое является сопоставлением от одного к ноль-одному. В частности:Сопоставление одно-нуля или одного с EF7
User -> UserSettings
Не все пользователи будут иметь пользовательские настройки, но пользовательские настройки не могут существовать без пользователя. К сожалению, таблицы уже существуют. User
имеет идентификатор ПК. UserSettings
имеет идентификатор PK и столбец User_Id_Fk
, который на данный момент не является истинным FK (отношения не определены).
Я в процессе исправления и сделал это с точки зрения БД через SQL и подтвердил с помощью тестов. (Добавлено ограничение FK. Добавлено уникальное ограничение на User_Id_Fk
.) Все это было сделано в таблице UserSettings
. (Примечание: я не использую EF Migrations здесь. Мне нужно вручную написать SQL в этот момент времени.)
Однако теперь мне необходимо подключить существующее приложение для правильной обработки этого нового сопоставления. Приложение использует ASP.NET Core 1.0 и EF7. Вот (сокращенные) версии существующих моделей данных.
public class User
{
public int Id { get; set; }
public virtual UserSettings UserSettings { get; set; }
}
public class UserSettings
{
public int Id { get; set; }
[Column("User_Id_Fk")]
public int UserId { get; set; }
[ForeignKey("UserId")]
public virtual User User { get; set; }
}
У меня есть этот свободный Mapping, а также:
builder.Entity<UserSettings>()
.HasOne(us => us.User)
.WithOne(u => u.User)
.IsRequired(false);
Когда я иду, чтобы запустить приложение и доступ к этим элементам в базе данных, я получаю эту ошибку, затем с загадочным набором сообщений, который имеет нет информации, относящейся непосредственно к моему заявлению .:
ArgumentNullException: Value cannot be null.
Parameter name: navigation
Microsoft.Data.Entity.Utilities.Check.NotNull[T] (Microsoft.Data.Entity.Utilities.T value, System.String parameterName) <0x10d28a650 + 0x00081> in <filename unknown>, line 0
После проведения исследований, кто-то упомянул, что идентификатор класса UserSettings должен быть таким же, как внешний ключ, Лик е так:
public class UserSettings
{
[Key, ForeignKey("User")]
public int Id { get; set; }
public virtual User User { get; set; }
}
Я на самом деле не это как вариант в качестве БД используется для других приложений, которые я не имеют никакого контроля над в этой точке. Итак, я застрял здесь? Должен ли я просто поддерживать отображение 1: много (что может произошло, хотя это не так) и не имеют надлежащих ограничений для отображения 1: 0..1?
Обновление Рассматривая ответ octavioccl ниже, я пробовал его без каких-либо успехов. Однако я удалил User
из картографирования в UserSettings
(но я оставил UserId
). Все, казалось, работало, насколько я могу судить. Однако я действительно запутался в том, что происходит здесь, и если это даже правильный ответ, или мне просто повезет.
Благодарим за отзыв. К сожалению, нет. Я немного смущен вашим ответом, когда у пользователя должен быть только нулевой или один пользовательский набор. Я не понимаю, как ваше решение достигает этого. (Это выходит за рамки того факта, что я все еще получаю ту же ошибку.) Могли бы вы дать разъяснения? Благодаря! – JasCav
Добавлено редактирование/обновление. – JasCav
Я видел ваше обновление сейчас, я думаю, что это работает, потому что EF видит теперь ваши отношения как одного для многих, а не как одного к одному. Когда вы объявляете только одно свойство навигации между связанными объектами, EF по умолчанию создает от одного до многих, я также путаю то, как работает ваша текущая модель, потому что, если у вас есть столбец FK в таблице UserSettings, в случае, если EF видит от одного до многих, свойство навигации коллекции должно быть объявлено в 'User', а не в качестве ссылочного навигационного свойства. В самом деле, очень смутно, позвольте мне снова подумать снова, если я найду что-то разумное, я сообщу – octavioccl