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

Issue in Default Mapping (ToListAsync<T>()) #812

Open
killJoy-03 opened this issue Aug 20, 2024 · 2 comments
Open

Issue in Default Mapping (ToListAsync<T>()) #812

killJoy-03 opened this issue Aug 20, 2024 · 2 comments
Assignees
Labels

Comments

@killJoy-03
Copy link

killJoy-03 commented Aug 20, 2024

I am comparing 2 versions of Neo4J Driver (v5.18.1 and v5.22.0)
Note - v5.18.1 user Neo4j.Driver.Preview.Mapping and v.5.22.0 uses Neo4j.Driver.Mapping namespace

  1. Both versions can't map NULL value
 Ex: MATCH (a:COL1)-[:REL1]->(b:COL2)
      OPTIONAL MATCH (c:COL3)
      RETURN { item1 : a , item2 : c.prop1 } // c may be null

This throws an exception like there is no value for item2.

  1. Older version can map directly to Models but newer version can't
    Ex:
 MATCH (a:COL1)
     RETURN a
 When I use cursor.ToListAsync<A>();
 2.1 Older version works fine.
 2.2 Newer version throws error due to Model A contains extra property which it doesn't find in DB result.
  1. In newer version as I mentioned direct model mapping is not working but there is something more
    Ex:
MATCH(a:COL1)
       RETURN {  prop1 : a.prop1 , prop2 : a.prop2 } // this is not working
       RETURN a.prop1 as prop1 , a.prop2 as prop2 // this is working  

Version Info :

  • .NET Version: .NET 9.0.100-preview.6.24328.19
  • .NET Driver Version 5.18.1 and 5.22.0
  • Neo4j Server Version & Edition Neo4J 5.21.0
@killJoy-03 killJoy-03 added the bug label Aug 20, 2024
@killJoy-03 killJoy-03 changed the title Issue in Default Mapping Issue in Default Mapping (ToListAsync<T>()) Aug 20, 2024
@killJoy-03
Copy link
Author

killJoy-03 commented Aug 29, 2024

Update:
@RichardIrons-neo4j
There is a bypass for example 3.

Example:

public record struct Collection<T>(List<T> Value);

MATCH(a:COL1)
       RETURN collect({  prop1 : a.prop1 , prop2 : a.prop2 }) as Values

This is working if we are mapping to Collection Model

@RichardIrons-neo4j
Copy link
Contributor

@killJoy-03 Hi.

What has happened is that there were some breaking changes made to the mapping code before it came out of preview. When it was in preview, the default mapper was case-insensitive, and also it was very forgiving as to where it might find the value for a property it was trying to set. For instance, if it was looking for "Name", it might find a property called "name" in a node that's in the "person" field of the record it's trying to map. In testing, we found a lot of cases where this could introduce ambiguity and unpredictability in the mapping code. The decision was made to make the mapper much more strict, and to require mapping to be done explicitly in cases where the property name (or constructor parameter name) doesn't match the name of a field.

For example, in the case above, instead of:

public class Example
{
	public string Name { get; set; }
}

you would need to have:

public class Example
{
	[MappingSource("person.name")]
	public string Name { get; set; }
}

And then it would find the value. If you have a property that is not going to receive a value, then you should mark that property with the [MappingIgnored] or [MappingDefaultValue] attributes. Constructor parameters can also be marked with these attributes (except for [MappingIgnored] as it doesn't make sense).

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

No branches or pull requests

2 participants