-
Notifications
You must be signed in to change notification settings - Fork 70
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
AsObject<T> on 5.21.0 throws MappingFailedException, did the behaviour change? #805
Comments
Well, I made a workaround but I am not sure if it is the best approach,
|
It got more complicated than I thought but I could solve it using chatgpt,
|
Hi there. The behaviour did change when the mapping went from preview to GA. If the case is different between the database and the code, you will need to be explicit about this. For example: public class TestEntity
{
[MappingSource("name")]
public string Name { get; set; }
[MappingOptional]
public int Age { get; set; }
[MappingDefaultValue("Unspecified")]
public string Nationality { get; set; }
} In the above example, we specify I hope this is useful information. |
@RichardIrons-neo4j would it be possible to allow us to pass a name mapper / or naming conventions instance in a similar way to json serialisation. I don't have control over the output model types or the input schema though the two share the same properties the naming conventions mean that they are stored as a_b and have property names in dotnet as Ab. |
@kevinoneill (sorry I forgot to @ you) Hi. There isn't currently a way to just provide a name translation service (which could be used for translating between naming conventions etc), although that is a good idea for a future feature. Something you can do right now is to implement something like the following: public class NameTranslationTests
{
private class FirstNameMappingTestObject
{
public string FavouriteColor { get; set; }
public int LuckyNumber { get; set; }
}
private class SecondNameMappingTestObject
{
public string JobTitle { get; set; }
public int YearsOfService { get; set; }
}
private class NamingConventionTranslator<T> : IRecordMapper<T>
{
private string GetTranslatedPropertyName(string fieldName)
{
// convert from snake_case to PascalCase
var capitaliseNext = true;
var result = "";
foreach (var c in fieldName)
{
if (c == '_')
{
capitaliseNext = true;
}
else
{
result += capitaliseNext ? char.ToUpper(c) : c;
capitaliseNext = false;
}
}
return result;
}
/// <inheritdoc />
public T Map(IRecord record)
{
// fields in the record will be like "something_else" and should be mapped to "SomethingElse" property
var type = typeof(T);
var obj = Activator.CreateInstance(type);
foreach (var field in record.Keys)
{
var property = type.GetProperty(GetTranslatedPropertyName(field));
if (property != null)
{
property.SetValue(obj, record[field]);
}
}
return (T)obj;
}
}
[Fact]
public void ShouldTranslateColumnNames()
{
var record1 = TestRecord.Create(("favourite_color", "blue"), ("lucky_number", 7));
var record2 = TestRecord.Create(("job_title", "developer"), ("years_of_service", 5));
// need to register a new instance for each type we're planning to map to
RecordObjectMapping.Register(new NamingConventionTranslator<FirstNameMappingTestObject>());
RecordObjectMapping.Register(new NamingConventionTranslator<SecondNameMappingTestObject>());
var obj1 = record1.AsObject<FirstNameMappingTestObject>();
var obj2 = record2.AsObject<SecondNameMappingTestObject>();
obj1.FavouriteColor.Should().Be("blue");
obj1.LuckyNumber.Should().Be(7);
obj2.JobTitle.Should().Be("developer");
obj2.YearsOfService.Should().Be(5);
}
} In this code the I hope this code is useful, and thanks for the idea about being able to inject a column name mapper! |
I found another solution to implement my own IRecord where the input is a object of type IReadOnly<string,object?> and recursive rename all the camel case into pascal case and then use AsObject(). But I got one issue with missing keys because T contains properties that is not returned. Would it be possible to turn off that as a option? |
Describe the bug
Neo4j.Driver.Mapping.MappingFailedException: 'Cannot map record to type X because the record does not contain a value for the property 'Y'.'
Did the behaviour change?
To Reproduce
Use AsObject on a class where returned type is camelcase and property is pascalcase
Expected behavior
It should map camelcase to pascalcase but not other way around and it should not matter if the property does not exists on the back-end side or it should be a optional configuration at least a option to disable it.
Version Info (please complete the following information):
The text was updated successfully, but these errors were encountered: