Repodb: Bug: Linq expression compare order matters

Created on 29 Dec 2020  路  8Comments  路  Source: mikependon/RepoDB

Not sure if this is bug or intended but I just got bitten by this.

I had a QueryAsync with multiple properties being compared (this also happens with only one).

Returns nothing as name parameter is null in query:

var persons = await connection.QueryAsync<Person>(x => input.Name == x.Name);

Returns correct results:

var persons = await connection.QueryAsync<Person>(x => x.Name == input.Name);

Library Version:

Example: RepoDb v1.12.4 and RepoDb.SqlServer v1.1.1

bug deployed wontfix working-as-expected

All 8 comments

Thanks for reporting this issue. Yes, this is on purpose, we only parse the bound properties on the left when building the compilations. In fact, we have place this on our limitation page, relating to unbound properties. We can leave this issue open for now, we will try to assess this in the future.

And apology, if you spent time finding the problem. :smile:

I tried to look around the documentation but couldn't find anything suitable for this case. Guess I should've picked it up from the unbound part, but I didn't associate it with my bug. Perhaps a note somewhere which stresses that the order of properties matter. We noobs don't understand your fancy words! 馃槃

Thank you for your swift reply and for this awesome project. All time lost debugging has been nothing compared to some other state of the art ORMs... 馃槂

Thanks. Can you give some simple small code snippets where the order of the properties are not working as expected? I will try to see if I can capture that on the master and guard it by the Integration Tests, and ofcourse, hopefully to include that on our upcoming release (very soon).

I tried to reproduce this in a new application but now I'm getting an exception.

Schema:

CREATE TABLE [dbo].[People]
(
    [Id]        [bigint]        NOT NULL,
    [FirstName] [nvarchar](32)  NOT NULL,
    [LastName]  [nvarchar](max) NOT NULL,
    [BirthDate] [date]          NOT NULL
        CONSTRAINT [PK_People] PRIMARY KEY CLUSTERED ([Id] ASC)
) ON [PRIMARY]
GO

Models:

public class Form
{
    public string Input { get; set; }
}

public class Person
{
    public long Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime BirthDate { get; set; }
}

Setup:

RepoDb.SqlServerBootstrap.Initialize();
RepoDb.FluentMapper
    .Entity<Person>()
    .Table("[dbo].[People]");

var person1 = new Person
{
    Id = 1,
    FirstName = "Test1",
    LastName = "Test1",
    BirthDate = new DateTime(2020, 12, 24)
};

var person2 = new Person
{
    Id = 2,
    FirstName = "Test2",
    LastName = "Test2",
    BirthDate = new DateTime(2020, 12, 25)
};

await using var connection = new SqlConnection(_connectionString);
await connection.MergeAllAsync(new List<Person> {person1, person2});

Test:

var input = new Form {Input = "Test1"};
var from = new DateTime(2020, 12, 24);
var to = new DateTime(2020, 12, 24);
var persons = (await connection.QueryAsync<Person>(x =>
    x.BirthDate >= from.Date && x.BirthDate <= to.Date && input.Input == x.LastName)).ToArray();

Exception:
Invalid expression '(value(Repro.Program+<>c__DisplayClass0_0).input.Input == x.LastName)'. The property Input is not defined on a target type 'Repro.Person'.

Not quite sure why I didn't get exception earlier. It only returned empty array for me.

Hey, yes! The issue is identical to the one reported, the one you posted. There is no Input Property from your entity, that is why. Can you try changing your query to the one below?

var persons = (await connection.QueryAsync<Person>(x =>
    x.BirthDate >= from.Date && x.BirthDate <= to.Date && x.LastName == input.Input)).ToArray();

Yea this works. When I first encountered this it didn't pop an exception tho. I just received an empty array.

Nice to know that it works. Thanks for verifying! 馃槂

Was this page helpful?
0 / 5 - 0 ratings