Skip to content
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

LINQ query dynamic component by interface hangs the application #3150

Closed
nfplee opened this issue Sep 3, 2022 · 10 comments · Fixed by #3154
Closed

LINQ query dynamic component by interface hangs the application #3150

nfplee opened this issue Sep 3, 2022 · 10 comments · Fixed by #3154

Comments

@nfplee
Copy link

nfplee commented Sep 3, 2022

I have the following query which executes fine:

var posts = await session.Query<BlogPost>()
    .Where(p => p.Attributes["Field1"] != null)
   .ToListAsync();

However if I change it to use an interface instead then the query hangs.

var posts = await session.Query<IBlogPost>()
    .Where(p => p.Attributes["Field1"] != null)
    .ToListAsync();

Please see the attached application which helps demonstrate this. This problem only happens when filtering against an attribute.

ConsoleApp1.zip

@bahusoid
Copy link
Member

bahusoid commented Sep 4, 2022

Infinite loop

while (metaData == null && targetObject != null &&
(targetObject.NodeType == ExpressionType.MemberAccess || targetObject.NodeType == ExpressionType.Parameter ||
targetObject is QuerySourceReferenceExpression))
{
System.Type memberType;
if (targetObject is QuerySourceReferenceExpression)
{
var querySourceExpression = (QuerySourceReferenceExpression) targetObject;
memberType = querySourceExpression.Type;
}
else if (targetObject.NodeType == ExpressionType.Parameter)
{
var parameterExpression = (ParameterExpression) targetObject;
memberType = parameterExpression.Type;
}
else //targetObject.NodeType == ExpressionType.MemberAccess
{
var memberExpression = ((MemberExpression) targetObject);
memberPath = memberExpression.Member.Name + "." + memberPath;
memberType = memberExpression.Type;
targetObject = memberExpression.Expression;
}
metaData = sessionFactory.GetClassMetadata(memberType);
}

Introduced in #237 (4.0.0.Alpha2)

@bahusoid
Copy link
Member

bahusoid commented Sep 5, 2022

It's not a regression. It didn't stuck before #237 but failed in some other way - dynamic components on unmapped interface never worked in LINQ

@bahusoid bahusoid changed the title LINQ query component by interface hangs the application LINQ query dynamic component by interface hangs the application Sep 5, 2022
@hazzik hazzik added p: Lowest and removed p: Minor labels Sep 6, 2022
@nfplee
Copy link
Author

nfplee commented Sep 6, 2022

@bahusoid do you have a suggestion for a temporary fix?

@bahusoid

This comment was marked as outdated.

@nfplee

This comment was marked as outdated.

@bahusoid

This comment was marked as outdated.

@nfplee
Copy link
Author

nfplee commented Sep 6, 2022

I already tried looking into this as this is what I do for my components. However the Class method is not available in the ClassMapping class. Looking into the code for the Class method against the ComponentMapping I tried adding:

CustomizersHolder.AddCustomizer(typeof(IBlogPost), m => m.Class(typeof(BlogPost)));

But this had no effect.

@bahusoid
Copy link
Member

bahusoid commented Sep 6, 2022

this is what I do for my components. However the Class method is not available in the ClassMapping class. Lo

Indeed. It seems I thought of component mapping myself. You can try to specify EntityName(typeof(IBlogPost).FullName) in your class mapping - but it should(?) work only for queries on interface. It will stuck for class.

@nfplee
Copy link
Author

nfplee commented Sep 7, 2022

Thanks @bahusoid that worked. Please note this doesn't fix the original issue, it just flips it so now when querying a dynamic component against the BlogPost class it hangs. This works better for me as my dynamic component is an attributes collection which allows me to dynamically add properties to my entities where I can't modify the concrete type, therefore I'm more likely to query the attributes against the IBlogPost abstraction.

@nfplee
Copy link
Author

nfplee commented Sep 8, 2022

I've decided that the fix of using EntityName(typeof(IBlogPost).FullName) in the mapping is actually the correct way to go as now I don't need to add conventions for my abstractions.

I debated closing out this issue but I'll leave it open as it would be better to throw an exception than get stuck an infinite loop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants