-
Notifications
You must be signed in to change notification settings - Fork 453
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
InvalidOperationException when using Poco-Class as Query Parameter #2546
Comments
Will handle that, thanks for reporting. |
Please include small mapping sample with model. It is not clear what happened here. |
You are crazy fast! Sure will try to make a simple mapping sample. |
I Modified a Test which you use in the class public class EagerLoadingTests. [Table]
class MasterClass
{
[Column] [PrimaryKey] public int Id1 { get; set; }
[Column] [PrimaryKey] public int Id2 { get; set; }
[Column] public string? Value { get; set; }
public string? Value2 { get; set; }
[Column] public byte[]? ByteValues { get; set; }
[Association(ThisKey = nameof(Id1), OtherKey = nameof(DetailClass.MasterId))]
public List<DetailClass> Details { get; set; } = null!;
[Association(QueryExpressionMethod = nameof(DetailsQueryImpl))]
public DetailClass[] DetailsQuery { get; set; } = null!;
static Expression<Func<MasterClass, IDataContext, IQueryable<DetailClass>>> DetailsQueryImpl()
{
return (m, dc) => dc.GetTable<DetailClass>().Where(d => d.MasterId == m.Id1 && d.MasterId == m.Id2 && d.DetailId % 2 == 0);
}
}
[Test]
public void Test([IncludeDataSources(TestProvName.AllSQLite)] string context)
{
var (masterRecords, detailRecords) = GenerateData();
var intParam = 0;
using (new AllowMultipleQuery())
using (var db = GetDataContext(context))
using (var master = db.CreateLocalTable(masterRecords))
using (var detail = db.CreateLocalTable(detailRecords))
{
db.MappingSchema
.GetFluentMappingBuilder()
.Entity<MasterClass>()
.Property(m => m.Value2)
.HasSkipOnInsert(true)
.HasSkipOnUpdate(true)
.IsExpression(x => Sql.Property<object>(x, "Value"), false);
var container = new MasterClass();
container.Value2 = "Hello World";
// this crashes
var something = (from x in db.GetTable<MasterClass>()
where x.Value2 != container.Value2
select x).ToList();
// this works
string valueString = container.Value2;
var something2 = (from x in db.GetTable<MasterClass>()
where x.Value2 != valueString
select x).ToList();
}
} |
One question, why |
This code normally runs in a foreach and is dynamically build fitting to the Database it is connected to. |
@sdanyliv i have modified the example a little, to get it closer to my real problem. So same Example as before, but "Value2" is our NoColumn Enum Property (instead of string). public enum TestEnum
{
a,
b,
c,
d
}
[Table]
class MasterClass
{
[Column] [PrimaryKey] public int Id1 { get; set; }
[Column] [PrimaryKey] public int Id2 { get; set; }
[Column] public string? Value { get; set; }
public TestEnum? Value2 { get; set; }
[Column] public byte[]? ByteValues { get; set; }
[Association(ThisKey = nameof(Id1), OtherKey = nameof(DetailClass.MasterId))]
public List<DetailClass> Details { get; set; } = null!;
[Association(QueryExpressionMethod = nameof(DetailsQueryImpl))]
public DetailClass[] DetailsQuery { get; set; } = null!;
static Expression<Func<MasterClass, IDataContext, IQueryable<DetailClass>>> DetailsQueryImpl()
{
return (m, dc) => dc.GetTable<DetailClass>().Where(d => d.MasterId == m.Id1 && d.MasterId == m.Id2 && d.DetailId % 2 == 0);
}
} And the Mapping code is now easier and i can reproduce it with this mapping code as well db.MappingSchema
.GetFluentMappingBuilder()
.Entity<MasterClass>()
.Property(m => m.Value2)
.HasSkipOnInsert(true)
.HasSkipOnUpdate(true)
.IsExpression(x => x.Value, false);
var container = new MasterClass();
container.Value2 = TestEnum.a;
var enumValue = container.Value2;
// this works
var something = (from x in db.GetTable<MasterClass>()
where x.Value2 != enumValue
select x).ToList();
// this doesn't
var something2 = (from x in db.GetTable<MasterClass>()
where x.Value2 != container.Value2
select x).ToList(); |
This code:
Generates this Exception:
But this Code works:
Apparently Linq2Db tries to translate the property of the POCO, although I only want the content. As long as i assign it to a variable before it is happy.
MyPocoClass.MyStringProperty is mapped with this code, which is the reason it crashes apparently:
We do that, because the Property is only there for convenience and this mapping helps us to have two properties for this one column. It normally works.
Now I think, because "MyStringProperty" is not a column, he crashes, when he sees it as a Value on the right side. And apparently the Expressionbuilder tries to build this property as "a column" instead of "a value".
If i remove the mapping code
// propertybuilder.IsExpression(x => Sql.Property<object>(x, otherPropertyName), false);
and make it a normal Db-Column, the Expressionbuilder is happy and accepts "container.MyStringProperty" and correctly makes it to a parameter in the query.
I think this is a bug, because the Expressionbuilder is apparently able to build a query with this property and he shoud not even try to build an expression out of container.MyStringProperty.
Environment details
linq2db version: 3.1.3
Database Server: Sql-Server 2019
Database Provider: Sql-Server 2019
Operating system: Windows 10
.NET Framework: 4.5.2
The text was updated successfully, but these errors were encountered: