Home > Software engineering >  SQlite EntityframeworkCore Linq query on column not working: InvalidOperationException
SQlite EntityframeworkCore Linq query on column not working: InvalidOperationException

Time:02-03

The Exception:

System.InvalidOperationException: 'The LINQ expression 'DbSet() .Where(k => (GroupAddress)k.Address == __notification_Destination_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 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'.

The source code which leads to the aforementioned exception
// works
var x = await dbContext.AddressConfigurations.SingleOrDefaultAsync(c => c.Id == 1);

// fails with the exception below
// Single() or First() makes no difference regarding the exception. Should be Single() but I have no unique constraint so far.
var y = await dbContext.AddressConfigurations.FirstOrDefaultAsync(c => c.Address == notification.Destination);
The database model
public class AddressConfiguration
{
    public AddressConfiguration(string address, string dataType)
    {
        Address = address;
        DataType = dataType;
    }

    public int Id { get; set; }

    public string Address { get; set; }

    public string DataType { get; set; }

    public string? Location { get; set; }
}

Is there anything I'm missing here? Do I need to define an index for that column?

CodePudding user response:

Based on the exception specifying cast to GroupAddress it seems that notification.Destination is a GroupAddress and there is implicit cast from string to it. Comparison of two arbitrary custom types can't be translated by EF AFAIK, so you need to convert notification.Destination to string. Depending on GroupAddress implementation you can try just an explicit cast (if it is implemented):

var y = await dbContext.AddressConfigurations
    .FirstOrDefaultAsync(c => c.Address == (string)notification.Destination);

Or ToString():

var y = await dbContext.AddressConfigurations
    .FirstOrDefaultAsync(c => c.Address == notification.Destination.ToString());

Or you will need to construct valid searchable string manually:

var y = await dbContext.AddressConfigurations
    .FirstOrDefaultAsync(c => c.Address == notification.Destination.SomeProp   " "   notification.Destination.SomeOtherProp);
  • Related