Closed AJHopper closed 6 years ago
@AJHopper Can you post a runnable project/solution or complete code listing that demonstrates the behavior you are seeing.
@ajcvickers Was setting up a small runnable solution that has the issue and seemingly couldnt get it to error - this lead me to delve into our codebase more and I found the issue was a redundant .HasConversion() call - the code runs fine without it but equally, as mentioned above it also runs fine with it in versions 2.1.1 and below, so will still post the code up to repro it.
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace ConsoleApp2
{
public abstract class Base
{
public int? Id { get; set; }
}
public class ObjectA : Base
{
public virtual ObjectB SomeObject { get; set; }
public int ObjectBId { get; set; }
}
public class ObjectB : Base
{
}
public class ObjectAMap : IEntityTypeConfiguration<ObjectA>
{
public void Configure(EntityTypeBuilder<ObjectA> builder)
{
builder.ToTable("FirstObject");
builder.HasKey(x => x.Id);
builder.Property(x => x.Id).HasColumnType("int");
builder.Property(x => x.ObjectBId).HasColumnType("int");
builder.HasOne(x => x.SomeObject).WithMany().HasForeignKey(x => x.ObjectBId).HasPrincipalKey(x => x.Id);
}
}
public class ObjectBMap : IEntityTypeConfiguration<ObjectB>
{
public void Configure(EntityTypeBuilder<ObjectB> builder)
{
builder.ToTable("SecondObject");
builder.HasKey(x => x.Id);
/*
* Below line seems to be the cause of the issue - somehow a redundant HasConversion was in one of our mappings.
*
* This does however work on EF Core 2.1.1 - though crashes on 2.1.2+
*/
builder.Property(x => x.Id).HasColumnType("float").HasConversion(x => x, x => (int)x);
}
}
public class MyDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=ADatabase;Database=TestRelations;Trusted_Connection=True;");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfiguration(new ObjectAMap());
modelBuilder.ApplyConfiguration(new ObjectBMap());
}
public DbSet<ObjectA> ObjectAs { get; set; }
public DbSet<ObjectB> ObjectBs { get; set; }
}
class Program
{
static void Main(string[] args)
{
using (var context = new MyDbContext())
{
var tt = context.ObjectAs.Include(x=> x.SomeObject).ToList();
}
}
}
}
@AJHopper Thanks for the additional info.
Triage: the issue here is that a conversion is defined for int?
to int?
but then used for an int
property. This probably should work given that the reverse (int
to int
but used for an int?
) is supposed to work. For example:
This fails:
builder.Property(x => x.Id).HasConversion(x => x, x => x);
This works:
builder.Property(x => x.Id).HasConversion(new ValueConverter<int,int>(x => x, x => x));
So, within our codebase we have had a setup that has been working on EF Core up to 2.1.1 however on versions beyond this fails with the Equal not defined issue - curious if this change is by design or a bug.
The issue being on a HasOne().WithMany() one way relationship mapping as detailed below where one of the fields it links on is an int type, and one is nullable int, as mentioned it works in 2.1.1 but tested in 2.1.2 and 2.1.4 its non-working with this issue.
Obviously a workaround would be to make the field nullable on both sides though this is essentially making a field which can never be null... into a nullable field just to get around an issue and since it works fine in 2.1.1 and prior I would like to not do that :) though would also like to be able to update versions without worry of breaking things
Steps to reproduce
So, steps to reproducing would be having the below class structure (havent tested variants but this is what we have), and doing a query for Entity1 calling .Include() on the Entity2 object.
Further technical details
EF Core version: 2.1.4 Database Provider: Microsoft.EntityFrameworkCore.SqlServer Operating system: Windows 10 64 bit Enterprise Edition IDE: Visual Studio 2017 15.8.4