0

I'm using Entity Framework Core with .NET 8 and trying to call a user-defined function from C# code.

I'm following the instructions here but have a slightly different use case. Rather than having the example from here:

var query1 = from b in context.Blogs
             where context.ActivePostCountForBlog(b.BlogId) > 1
             select b;

which generates this SQL:

SELECT [b].[BlogId], [b].[Rating], [b].[Url]
FROM [Blogs] AS [b]
WHERE [dbo].[CommentedPostCountForBlog]([b].[BlogId]) > 1

I would like to write an expression that generates the SQL:

SELECT ActivePostCountForBlog(123)

where 123 is a blog ID I already know.

I've tried:

var blogId = 123;
    
var query1 = context.ActivePostCountForBlog(blogId);

but this doesn't call the OnModelCreating method, which I assume is because I'm not using any of the model classes. This then doesn't map to the UDF.

The closest I've got is with (in fluent syntax since it's what I'm used to):

var blogId = 123;

context.Blogs
        .Where(b => b.BlogId == blogId)
        .Select(b => context.ActivePostCountForBlog(b.BlogId))
        .SingleOrDefault();

but this creates suboptimal SQL that ends up using a poorer execution plan:

SELECT TOP(2) [dbo].[CommentedPostCountForBlog]([b].[BlogId])
FROM [Blogs] AS [b]
WHERE [b].[BlogId] = 123

Is there any way I can call the UDF without having to select from the Blogs table? I've also got no idea where the TOP(2) is coming from! But I'll settle for an answer to the bigger issue.

1
  • EF do not have possiblity to just call UDF in LINQ query without using real table. TOP 2 is because you have used SingleOrDefault , with FirstOrDefault it will be TOP 1. System is tring to select 2 records to to validate that only one or zero is returned. Commented Jun 5 at 15:03

0