Consider the following Func
which takes in the DbSet
and returns the result contract:
public static Func<Repository.DataSets.Person, Person> Map(IPersonGetOptions options)
{
return k => new Person()
{
ID = k.ID,
Department = k.Department == null ? null : new Department()
{
ID = k.Department.ID,
};
};
}
Department Func
:
public static Func<Repository.DataSets.Department, Department> MapDepartment()
{
return k => new Department()
{
ID = k.ID,
};
}
Usage:
public Person GetById(int id, PersonGetOptions options = null)
{
options ??= new();
var result = db.Persons
.Select(Map(options))
.FirstOrDefault(k => k.ID == id);
return result;
}
// similar for department: ... db.Departments.Select(Map()) ...
I want to reuse MapDepartment
in Map
in a way EF can translate (I don't want to use AutoMapper).
What I tried:
public static Func<Repository.DataSets.Person, Person> Map(IPersonGetOptions options)
{
return k => new Person()
{
ID = k.ID,
Department = k.Department == null ? null : MapDepartment().Invoke(k.Department)
};
}
This code block won't work as it cannot be translated by efcore (v5). Any idea how to make this work?
With @Svyatoslav Danyliv comment linked to a similar post, What I tried:
With LINQkit, I was able to accomplish a reusable Func
without arguments. but it did not seem to be working when adding arguments like options
in my example:
This works:
[Expandable(nameof(Map))]
private static Offer MapPerson(Repository.DataSets.Person k)
{
_map ??= Map().Compile();
return _map(k);
}
private static Func<Repository.DataSets.Person, Person> _map;
public static Expression<Func<Repository.DataSets.Person, Person>> Map(){
...
}
// usage
```cs
.Select(k => MapPerson(k))
But when introducing an argument options
, it will throw the following:
No method 'Map' on type 'my-namespace.my-class' is compatible with the supplied arguments
Failed code:
private static Offer MapPerson(IPersonGetOptions options, Repository.DataSets.Person k){
_map ??= Map(options).Compile();
return _map(k);
}
private static Func<Repository.DataSets.Person, Person> _map;
public static Expression<Func<Repository.DataSets.Person, Person>> Map(IPersonGetOptions options){
...
}