Я действительно новичок в EF (использую EF core 2.1) и до сих пор следил за кучей руководств, но теперь я решил создать свою собственную структуру БД и споткнулся при попытке добавить значение в БД:
private async Task<int> Insert()
{
var address = new Address { AddressLine1 = "1 any street", AddressLine2 = "", AddressLine3 = "", City = "Any city" };
using (var context = new BranchContext())
{
context.Addresses.AddAsync(address);//ERROR HERE
....
}
}
Я получаю сообщение об ошибке:
InvalidOperationException: The property 'Branch.Address' is of type 'Address' which is not supported by current database provider. Either change the property CLR type or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
Я создал следующие классы:
public class Address
{
public int Id { get; set; }
public int Guid { get; set; }
public DateTime CreatedOn { get; set; }
public string Number { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string Town { get; set; }
public string City { get; set; }
public string Postcode1 { get; set; }
public string Postcode2 { get; set; }
public string Latitude { get; set; }
public string Longitude { get; set; }
}
public class Branch
{
public string Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
public IEnumerable<EmployeeBranch> Employee { get; set; }
public bool IsMain { get; set; }
}
public class Employee
{
public int Id { get; set; }
public string Guid { get; set; }
public string EmailAddress { get; set; }
public JobTitle JobTitle { get; set; }
public DateTime DateOfBirth { get; set; }
public IEnumerable<EmployeeBranch> Branches { get; set; }
public Branch PrimaryBranch { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string PreferredName { get; set; }
public Salutations Salutation { get; set; }
}
public enum Salutations
{
Mr = 1,
Mrs = 2,
Miss = 3,
Ms = 4
}
public class EmployeeBranch
{
public int BranchId { get; set; }
public Branch Branch { get; set; }
public int EmployeeId { get; set; }
public Employee Employee { get; set; }
}
public class JobTitle
{
public int Id { get; set; }
public string Guid { get; set; }
public string Name { get; set; }
}
Затем я побежал:
Add-Migration init
Update-Database
Было создано следующее:
Чтобы было ясно, что это ошибка времени выполнения, я просмотрел несколько потоков, которые получают эту ошибку, когда пытаются обновить свои базы данных здесь и здесь, но их обсуждения не указали мне правильное направление (возможно, я упускаю очевидное).
Как решить эту проблему? Желательно без изменения структуры, хотя я рад, если есть веская причина для этого.





Кажется, в конце концов это был довольно простой ответ, ошибка заставила меня посмотреть на структуру моих классов и попытаться понять, что пошло не так. Проблема заключалась в том, что в моем BranchContext (который я не учел в своем вопросе) я подключился к OnModelCreating и установил адрес по мере необходимости.
Неправильно
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<EmployeeBranch>()
.HasKey(s => new { s.BranchId, s.EmployeeId });
modelBuilder.Entity<Branch>()
.Property(s => s.Address).IsRequired();
modelBuilder.Entity<Branch>()
.Property(s => s.Name).IsRequired();
base.OnModelCreating(modelBuilder);
}
Верно
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<EmployeeBranch>()
.HasKey(s => new { s.BranchId, s.EmployeeId });
modelBuilder.Entity<Address>()
.Property(s => s.AddressLine1).IsRequired();
modelBuilder.Entity<Address>()
.Property(s => s.Postcode1).IsRequired();
modelBuilder.Entity<Address>()
.Property(s => s.Postcode2).IsRequired();
...the other required elements...
modelBuilder.Entity<Branch>()
.Property(s => s.Name).IsRequired();
base.OnModelCreating(modelBuilder);
}
Предположение: цель состоит в том, чтобы сделать Address необходимым свойством Branch
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Branch>()
.HasOne(s => s.Address)
.WithMany()
.IsRequired();
}
You can use the Fluent API to configure whether the relationship is required or optional
Источник: Обязательные и необязательные отношения
Эта ошибка также может появляться в глупых ситуациях ссылки на свойство навигации вместо сопоставленного свойства в ограничении или подобном:
modelBuilder.Entity<TheEntity>().HasKey(ma => new { ma.SomeKey, ma.NavPropInsteadOfProp });
К сожалению, ошибка недостаточно явная, но временное закомментирование виновника ошибки приведет к источнику.
Спасибо, была именно моя ситуация. Вы, вероятно, сэкономили мне 30 минут по крайней мере
Совершенно потрясающее предложение. Вы только что сэкономили мне много времени на загадки.
Я также ссылался на свойство навигации... но не для определения ключа... это было, когда я пытался сопоставить с конкретным именем столбца.
Это было для меня. Спасибо, что упомянули об этом здесь. Моему помогло исправить