The property X is of type Y which is not supported by current database provider
Asked Answered
K

3

27

I am really new to EF (using EF core 2.1) and have been following a bunch of tutorials so far, but now I have ventred in to creating my own DB structure and stumbled when trying to add a value in to the DB:

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
        ....
    }
 }

I get the error:

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'.

I have created the following Classes:

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; }
}

I then ran:

Add-Migration init
Update-Database

The following was created:

DB structure

To be clear this is a runtime error, I have viewed couple of threads that get this error when they try to update their db here and here but their discussions have not pointed me in the right direction (maybe I'm missing the obvious).

How do I resolve this? Preferably without Channing the structure, although I'm happy to if there is a good reason to do so

Korwin answered 3/5, 2019 at 22:14 Comment(0)
K
7

It seems it was a fairly simple answer in the end, the error had me looking at the structure of my classes and trying to work out what had gone wrong. The problem was that in my BranchContext (which I did not consider sharing in my question), I hooked into OnModelCreating and set Address as required

Wrong

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);
}

Right

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);
}
Korwin answered 18/5, 2019 at 20:7 Comment(1)
Let me clarify this solution for those who didn't see it at first like I did. The PO was trying to do this: Address.IsRequired() instead of Address.PostalCode1.IsRequired(). Check your configuration on the classes referencing the problem class, that's where the problem lies.Hyozo
F
32

This error might also pop up in silly situations of referencing a navigation property instead of a mapped property within a constraint or similar:

modelBuilder.Entity<TheEntity>().HasKey(ma => new { ma.SomeKey, ma.NavPropInsteadOfProp });

Unfortunately, the error is not explicit enough, but temporarily commenting out the culprit from the error will lead to the source.

Forereach answered 7/7, 2020 at 16:43 Comment(4)
This was it for me. Thank you for mentioning this here. It helped fix mineFrancesfrancesca
Thanks, was exactly my situation. You probably saved me 30 minutes at leastAtalee
Absolutely awesome suggestion. You just saved me lots of time puzzling.Inefficiency
I referenced the navigation property too...but not for defining the Key...it was when I tried to map to a specific column name.Obed
S
8

Assumption: the goal is to make Address a required property of 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

Source: Required and Optional Relationships

Smear answered 20/8, 2019 at 17:7 Comment(0)
K
7

It seems it was a fairly simple answer in the end, the error had me looking at the structure of my classes and trying to work out what had gone wrong. The problem was that in my BranchContext (which I did not consider sharing in my question), I hooked into OnModelCreating and set Address as required

Wrong

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);
}

Right

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);
}
Korwin answered 18/5, 2019 at 20:7 Comment(1)
Let me clarify this solution for those who didn't see it at first like I did. The PO was trying to do this: Address.IsRequired() instead of Address.PostalCode1.IsRequired(). Check your configuration on the classes referencing the problem class, that's where the problem lies.Hyozo

© 2022 - 2024 — McMap. All rights reserved.