1

I have this model as you can see here :

public  class car
    {
        public int Id { set; get; }
        public string Name { set; get; }
        public CarBody CarBody { get; set; }

        public car( string name, CarBody carBody)
        {

            Name = name;
            CarBody = new CarBody(carBody.VIN);
        }
        private car()
        {

        }
    }

And inside this class car I have another value object named CarBody

   public class CarBody
{
    public VIN VIN { get; set; }

    public CarBody(VIN vin)
    {
        VIN = vin;
    }

    private CarBody()
    {

    }
}

And VIN Model

public class VIN
    {
        public string value { get; set; }

        public VIN(string value)
        {
            this.value = value;
        }

        private VIN()
        {

        }
    }

I need to execute a query using EFCORE 3.1 on VIN inside CarBody as you can see here :

  public Domain.PetrolReceptions.PetrolReception GetLastOpenNotCanceledByVIN(string vin,
        double openPetrolTestTimeInDays)
    {


        var result = _dbContext.PetrolReceptions.Where(g =>g.Car.carBody.vin == vin ).ToList();

        return result.FirstOrDefault();
    }

But after executing the query I got this error:

The LINQ expression 'DbSet<PetrolReception>
    .Where(p => p.Car.carBody.vin == __vin_0)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

Here is the configEntity configuration

 public  class CarConfig : IEntityTypeConfiguration<car>
    {

        public void Configure(EntityTypeBuilder<car> builder)
        {
            builder.Property(c => c.CarBody).HasConversion(c => JsonConvert.SerializeObject(c),
                c => JsonConvert.DeserializeObject<CarBody>(c));

        }
    }

Thanks in Advance.

Ehsan Akbar
  • 6,977
  • 19
  • 96
  • 180
  • Many things are missing from the picture - `Money`, `CarBrand`, `Year`, `CarColor`, `PlaqueCode`. Eliminating them from the model, and configuring `Car` and `CarBody` as owned entity types, gives different exception "No suitable constructor found for entity type 'Car'. " Adding `private Car() { }` to `Car` class gives no exception, i.e. in both cases the issue cannot be reproduced. Please provide [mre]. – Ivan Stoev May 10 '20 at 08:51
  • @IvanStoev I have same problems on money and other models ,but in my example I describe VIN \ – Ehsan Akbar May 10 '20 at 09:47
  • I believe you, but cannot reproduce. Update your example in a way that we can copy/paste the model + fluent configuration (if any) in a clean project, run the query and get the exception in question. Apparently you have an issue, but without repro we cannot tell you what's causing it and how to eventually resolve it. – Ivan Stoev May 10 '20 at 09:55
  • @IvanStoev Thank you Ivan ,I edit my post with a simple example . – Ehsan Akbar May 10 '20 at 10:25
  • Aha, Json value converter (I was assuming owned entity). Sorry, from EF/db standpoint, `p.Car` is just a `string`, hence any property accessors inside cannot be translated to SQL. So client evaluation is the only option. Except if you are using SqlServer and somehow utilize the `JSON_VALUE` function (here https://stackoverflow.com/questions/52017204/expression-tree-to-sql-with-ef-core/52018037#52018037 you can see how to enable it). In general storing Json in relational database is a bad idea, especially with the lack of Json data type in EF Core. – Ivan Stoev May 10 '20 at 10:51
  • @IvanStoev Can I use dapper ? – Ehsan Akbar May 10 '20 at 10:59
  • Hey this needs a lot of expansion in the question. But essentially the answer to the problem, it an equality comparison... ` carbody.Vin is an object` and the passed in value is a string; I assume this is the vinNumber, rather than the Vin. Think Vin as an Entity (contains number, and related attributres), Where as `string vin` in really the vinNumber. In other words, you are `Ehsan Akbar` (the person), and your name is `Ehsan Akbar` - you the person is not equal to you the name (if person == name). – mrdnk May 10 '20 at 21:39

1 Answers1

1

Finally in use owntype in EFCORE 3.1 because as I found the EFCORE3.1 doesn't support it .

  public  class CarConfig : IEntityTypeConfiguration<car>
    {

        public void Configure(EntityTypeBuilder<car> builder)
        {
            builder.OwnsOne(c => c.CarBody).OwnsOne(c => c.VIN);

        }
    }

Thank you .

Ehsan Akbar
  • 6,977
  • 19
  • 96
  • 180