Mapowanie wbudowanych i własnych funkcji

0

Czołem

Zgodnie z tym artykułem https://learn.microsoft.com/en-us/ef/core/querying/user-defined-function-mapping próbowałem zmapować do EF najpierw wbudowaną funkcję SQL Server tj DATENAME.

public string DateName(string arg, DateTime date) => throw new InvalidOperationException($"{nameof(DateName)} cannot be called client side.");

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    var dateNameMethodInfo = typeof(DbContext)
        .GetRuntimeMethod(nameof(DbContext.DateName), new[] { typeof(string), typeof(DateTime) });

    builder.HasDbFunction(dateNameMethodInfo)
       .HasTranslation(args =>
                new SqlFunctionExpression("DATENAME",
                new[]
                {
                    new SqlFragmentExpression((args.ToArray()[0] as SqlConstantExpression).Value.ToString()),
                    args.ToArray()[1]
                },
                true,
                new[] { false, false },
                typeof(string),
                null));
}

Niestety, ale dla powyższego sposobu dostaję wyjątek:

The LINQ expression 'DbSet<WorkingDay>()
    .Where(n => ___dbContext_0.DateName(
        arg: "weekday", 
        date: n.WorkingDayDate) == "Monday")' could not be translated. Additional information: Translation of method 'Chancellor.Application.Common.DbContexts.IChancellorDbContext.DateName' failed. If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

Zrobiłem też dokładnie tak jak w przytoczonym artukule tj opakowałem DATENAME w moją funkcję WrappedDateName

CREATE FUNCTION [dbo].[WrappedDateName](@date DATE, @returnType VARCHAR(10))
RETURNS VARCHAR(9)
AS
BEGIN
	IF (@returnType = 'weekday')
		RETURN DATENAME(weekday, @date);

	RETURN NULL;
END

Następnie dodałem mapowanie na metodę i translację:

public string DateName(string arg, DateTime date) => throw new InvalidOperationException($"{nameof(DateName)} cannot be called client side.");

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    builder.HasDbFunction(trDbContext).GetMethod(nameof(DateName), new[] { typeof(string), typeof(DateTime) }))
          .HasName("WrappedDateName");
}


builder.HasDbFunction(typeof(ChancellorDbContext).GetMethod(nameof(DateName), new[] { typeof(string), typeof(DateTime) }))
                   .HasName("WrappedDateName");

Dostaję wyjątek:

The LINQ expression 'DbSet<WorkingDay>()
    .Where(n => ___dbContext_0.DateName(
        arg: "weekday", 
        date: n.WorkingDayDate) == "Monday")' could not be translated. Additional information: Translation of method 'Chancellor.Application.Common.DbContexts.IChancellorDbContext.DateName' failed. If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

W drugim przypadku robię identycznie jak w artykule MS.
Ktoś może podpowiedzieć jak to zrobić aby działało?

Nie chcę pobierać zestawu do pamięci i robić porównanie po stronie aplikacji skoro Sql Server ma taką funkcję wbudowaną.

1

Pierwsze co mi się rzuca w oczy to funkcja w SQL ma pierwszy argument Date a drugi string. W kodzie jest na odwrót

0
szydlak napisał(a):

Pierwsze co mi się rzuca w oczy to funkcja w SQL ma pierwszy argument Date a drugi string. W kodzie jest na odwrót

Poprawiłem, ale dalej ten sam komunikat. Totalnie nie rozumiem co jest nie tak skoro robię tak samo jak w materiałach MS.

1 użytkowników online, w tym zalogowanych: 0, gości: 1