Reuse the same value converter instance when configured as type
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
When a query uses the same parameter in several locations, Entity Framework may not detect the parameter as being the same parameter and will parameterize several instances of the same parameter.
Take for example the following LINQ:
```cs
dbContext.Projects
.Join(
dbContext.ProjectTranslations,
outer => new {
outer.ProjectId,
TranslationId = translationId
},
inner => new {
inner.ProjectId,
inner.TranslationId
},
(outer, inner) => new {
Project = outer,
ProjectTranslation = inner
}
)
.Join(
dbContext.ProjectCategoryTranslations,
outer => new {
outer.Project.ProjectCategoryId,
TranslationId = translationId
},
inner => new {
inner.ProjectCategoryId,
inner.TranslationId
},
(outer, inner) => new {
outer.Project,
outer.ProjectTranslation,
ProjectCategoryTranslation = inner
}
)
.Join(
dbContext.Builders,
outer => outer.Project.BuilderId,
inner => inner.BuilderId,
(outer, inner) => new {
outer.Project,
outer.ProjectTranslation,
outer.ProjectCategoryTranslation,
Builder = inner
}
)
.Join(
dbContext.DirectoryCategoryTranslations,
outer => new {
outer.Builder.DirectoryCategoryId,
TranslationId = translationId
},
inner => new {
inner.DirectoryCategoryId,
inner.TranslationId
},
(outer, inner) => new
{
outer.Project,
outer.ProjectTranslation,
outer.ProjectCategoryTranslation,
outer.Builder,
DirectoryCategoryTranslation = inner,
}
)
.FirstOrDefaultAsync();
```
This will generate the following command:
```
Executed DbCommand (39ms) [Parameters=[
@__translationId_0='?' (DbType = Int32),
@__translationId_0_1='?' (DbType = Int32),
@__translationId_0_2='?' (DbType = Int32),
@__projectId_1='?' (DbType = Int32)
], CommandType='Text', CommandTimeout='30']
```
Now that `EF.Parameter` is available with Entity Framework 9, perhaps this could be improved with an optional name passed to the method. Something like the following?
```cs
dbContext.Projects
.Join(
dbContext.ProjectTranslations,
outer => new {
outer.ProjectId,
TranslationId = EF.Parameter(translationId, "translationId")
},
inner => new {
inner.ProjectId,
inner.TranslationId
},
(outer, inner) => new {
Project = outer,
ProjectTranslation = inner
}
)
.Join(
dbContext.ProjectCategoryTranslations,
outer => new {
outer.Project.ProjectCategoryId,
TranslationId = EF.Parameter(translationId, "translationId")
},
inner => new {
inner.ProjectCategoryId,
inner.TranslationId
},
(outer, inner) => new {
outer.Project,
outer.ProjectTranslation,
ProjectCategoryTranslation = inner
}
)
.Join(
dbContext.Builders,
outer => outer.Project.BuilderId,
inner => inner.BuilderId,
(outer, inner) => new {
outer.Project,
outer.ProjectTranslation,
outer.ProjectCategoryTranslation,
Builder = inner
}
)
.Join(
dbContext.DirectoryCategoryTranslations,
outer => new {
outer.Builder.DirectoryCategoryId,
TranslationId = EF.Parameter(translationId, "translationId")
},
inner => new {
inner.DirectoryCategoryId,
inner.TranslationId
},
(outer, inner) => new
{
outer.Project,
outer.ProjectTranslation,
outer.ProjectCategoryTranslation,
outer.Builder,
DirectoryCategoryTranslation = inner,
}
)
.FirstOrDefaultAsync();
```
Contributor guide
Assessment
This issue has not been assessed yet.