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

Dynamic.DynamicIndex is exposed in the expression #448

Closed
hazzik opened this issue Nov 2, 2020 · 17 comments
Closed

Dynamic.DynamicIndex is exposed in the expression #448

hazzik opened this issue Nov 2, 2020 · 17 comments
Assignees
Labels

Comments

@hazzik
Copy link
Contributor

hazzik commented Nov 2, 2020

After upgrading from 1.1.8 to 1.2.0 I'm getting MethodNotSupported exception because my expression parser finds Dynamic.DynamicIndex(object, string) method in the expression. Strangely this method was introduced in 1.1.8, but the error started happening only in 1.2.0

Here are the failing tests: https://ci.appveyor.com/project/hazzik/nhibernate-core/builds/35962348/job/uvi4bg3jew1giw41/tests

@StefH
Copy link
Collaborator

StefH commented Jan 20, 2021

Hello @hazzik, thanks for reporting.

I'll take a look.

@StefH
Copy link
Collaborator

StefH commented Jan 21, 2021

@hazzik
Can you provide a full source code example which displays this error?

@hazzik
Copy link
Contributor Author

hazzik commented Jan 21, 2021

It is here:

https://github.com/nhibernate/nhibernate-core/blob/d6e054f2bbfda43fccf82d54b7cda4e5aecbab5d/src/NHibernate.Test/NHSpecificTest/NH2664Dynamic/Fixture.cs#L75-L88

public class Product
{
    public virtual string ProductId { get; set; }

    public virtual dynamic Properties { get; set; }
}

public void Query_DynamicComponent()
{
    using (var session = OpenSession())
    {
        var product = session
            .Query<Product>()
            .Where("Properties.Name == @0", "First Product") // <-- here
            .Single();

        Assert.That(product, Is.Not.Null);
        Assert.That((object) product.Properties["Name"], Is.EqualTo("First Product"));
        Assert.That((object) product.Properties.Name, Is.EqualTo("First Product"));
    }
}

@hazzik
Copy link
Contributor Author

hazzik commented Jan 21, 2021

This is the simplest reproduction: https://dotnetfiddle.net/8Az1F6

It outputs

Product[].Where(Param_0 => (DynamicIndex(Param_0.Properties, "Name") == Convert("First Product", Object)))

And DynamicIndex method call is a problem here, because I would need to make NHibernate aware of this method to correctly parse the expression on 1.2.0

@StefH
Copy link
Collaborator

StefH commented Jan 22, 2021

Hello @hazzik,
I think I found a possible fix for this issue, however I want to test this using NHibernate.
Can you please provide me with a minimal console-app which can reproduce this issue?

@StefH
Copy link
Collaborator

StefH commented Jan 27, 2021

Dear @hazzik , can you please provide a minimal console-app to reproduce this issue?

@hazzik
Copy link
Contributor Author

hazzik commented Jan 27, 2021

I'll do it on or by this weekend.

@StefH StefH self-assigned this Jan 31, 2021
@StefH StefH added the bug label Jan 31, 2021
@hazzik
Copy link
Contributor Author

hazzik commented Feb 2, 2021

@StefH here is the console app with reproduction: https://github.com/hazzik/nhibernate-linq-dynamic

@StefH
Copy link
Collaborator

StefH commented Feb 3, 2021

@hazzik Thank you very much, I'll copy this example to verify/reproduce the bug.

@StefH
Copy link
Collaborator

StefH commented Feb 3, 2021

I'm working on a fix, but dynamic cannot be supported.

This is also not supported in normal code:
image

The code is reworked that this scenario can work:

class Product
	{
		public virtual Guid Id { get; set; }
		public virtual string Name { get; set; }
		public virtual IDictionary<string, object> Properties { get; set; }   // <--
	}

with:

var properties1 = new Dictionary<string, object>
{
	["Name"] = "First Product",
	["Description"] = "First Description"
};
session.Save(
	new Product
	{
		Id = Guid.NewGuid(),
		Properties = properties1
	});

//var properties2 = new
//{
//	Name = "Second Product",
//	Description = "Second Description"
//};
//session.Save(
//	new Product
//	{
//		Id = Guid.NewGuid(),
//		Properties = properties2
//	});

dynamic properties3 = new ExpandoObject();
properties3.Name = "Third Product";
properties3.Description = "Third Description";
session.Save(
	new Product
	{
		Id = Guid.NewGuid(),
		Properties = properties3
	});

And this works:

var x = session.Query<Product>().Where(p => p.Properties["Name"] == "First Product").ToList();

				var y = session.Query<Product>()
					.Where("Properties.Name == @0", "First Product")
					.ToList();

@hazzik
Copy link
Contributor Author

hazzik commented Feb 3, 2021

I'm working on a fix, but dynamic cannot be supported.

This code was working fine in 1.1.8. I know that dynamic expressions are supported in the linq-tree, but not supported on a language level. To properly support them it would probably be required to depend on Microsoft.CSharp package.

@StefH
Copy link
Collaborator

StefH commented Feb 4, 2021

@hazzik
I did test previous versions.

However it seems that 1.1.7 does work, and higher versions fail with:
Unhandled exception. System.NotSupportedException: System.Object DynamicIndex(System.Object, System.String)

Correct ?

@hazzik
Copy link
Contributor Author

hazzik commented Feb 4, 2021

Yes, that is correct. I might misremembered the working version due it is being long time since I've tested it myself.

@StefH
Copy link
Collaborator

StefH commented Feb 4, 2021

@StefH
Copy link
Collaborator

StefH commented Feb 9, 2021

Hello @hazzik , did you have time to test this preview package?

@StefH
Copy link
Collaborator

StefH commented Feb 10, 2021

Hello @hazzik,

Thanks a lot for your analysis and help.

In some day(s) , I'll merge this PR and create a new official 1.2.8 NuGet package

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

No branches or pull requests

2 participants