最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - How do you map a multi-statement table valued function in Entity Framework Core 9? - Stack Overflow

programmeradmin11浏览0评论

As the question says, exiting documentation on the Microsoft Learn website (Mapping a queryable function to a table-valued function) doesn't describe how to configure these types of functions.

How do you map these types of function in EF Core given that the returned table doesn't exist?

Test function

CREATE FUNCTION [dbo].[fn_multi_statement_test]
(
    @p1 INT
)
RETURNS @OutputTable TABLE
(
    [Id] INT,
    [Name] NVARCHAR(50)
)
AS

BEGIN

    DECLARE @Apple AS TABLE
    (
        [Name] NVARCHAR(50)
    )

    INSERT INTO @Apple ([Name]) SELECT 'Apple'

    DECLARE @Pear AS TABLE
    (
        [Name] NVARCHAR(50)
    )

    INSERT INTO @Pear ([Name]) SELECT 'Pear'

    INSERT INTO @OutputTable ([Id], [Name]) SELECT @p1, [Name] FROM @Apple
    INSERT INTO @OutputTable ([Id], [Name]) SELECT @p1, [Name] FROM @Pear
RETURN
END;

EF Configuration

// MultiStatementTest.cs

public class MultiStatementTest
{
    public int Id { get; set; }
    public string Name { get; set; }
}

// Context.OnModelCreatingPartial.cs

public partial class Context
{
    public IQueryable<MultiStatementTest> fn_multi_statement_test(int p1)
    {
        return FromExpression(() => fn_multi_statement_test(p1));
    }

    partial void OnModelCreatingPartial(ModelBuilder modelBuilder)
    {
        // What table name should be used here?
        modelBuilder.Entity<MultiStatementTest>().ToTable(?);
        
        modelBuilder
        .HasDbFunction(typeof(Context).GetMethod(nameof(fn_multi_statement_test), new[] { typeof(int) }))
        .HasName("fn_multi_statement_test")
        .HasSchema("dbo");
    }
}

Any help/guidance is appreciated.

Thanks.

As the question says, exiting documentation on the Microsoft Learn website (Mapping a queryable function to a table-valued function) doesn't describe how to configure these types of functions.

How do you map these types of function in EF Core given that the returned table doesn't exist?

Test function

CREATE FUNCTION [dbo].[fn_multi_statement_test]
(
    @p1 INT
)
RETURNS @OutputTable TABLE
(
    [Id] INT,
    [Name] NVARCHAR(50)
)
AS

BEGIN

    DECLARE @Apple AS TABLE
    (
        [Name] NVARCHAR(50)
    )

    INSERT INTO @Apple ([Name]) SELECT 'Apple'

    DECLARE @Pear AS TABLE
    (
        [Name] NVARCHAR(50)
    )

    INSERT INTO @Pear ([Name]) SELECT 'Pear'

    INSERT INTO @OutputTable ([Id], [Name]) SELECT @p1, [Name] FROM @Apple
    INSERT INTO @OutputTable ([Id], [Name]) SELECT @p1, [Name] FROM @Pear
RETURN
END;

EF Configuration

// MultiStatementTest.cs

public class MultiStatementTest
{
    public int Id { get; set; }
    public string Name { get; set; }
}

// Context.OnModelCreatingPartial.cs

public partial class Context
{
    public IQueryable<MultiStatementTest> fn_multi_statement_test(int p1)
    {
        return FromExpression(() => fn_multi_statement_test(p1));
    }

    partial void OnModelCreatingPartial(ModelBuilder modelBuilder)
    {
        // What table name should be used here?
        modelBuilder.Entity<MultiStatementTest>().ToTable(?);
        
        modelBuilder
        .HasDbFunction(typeof(Context).GetMethod(nameof(fn_multi_statement_test), new[] { typeof(int) }))
        .HasName("fn_multi_statement_test")
        .HasSchema("dbo");
    }
}

Any help/guidance is appreciated.

Thanks.

Share Improve this question edited 2 days ago Zhi Lv 21.5k1 gold badge27 silver badges37 bronze badges asked Feb 5 at 2:50 User28487024User28487024 152 bronze badges 1
  • 1 The same way you define any query type learn.microsoft.com/en-us/ef/core/modeling/…. – Jeremy Lakeman Commented Feb 5 at 3:06
Add a comment  | 

1 Answer 1

Reset to default 0

Your example may not work as you expect since you are inserting the provided value in as the ID of both rows and returning them in a combined set. You would need to define your entity as Keyless:

[Keyless]
public class MultiStatementTest
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Otherwise you would get back 2 rows, with a single reference reporting as "Apple" if "Id" is interpreted as the Key. (default behaviour with that naming convention)

For the declaration you would need a method in your DbContext to both map to the DbFunction and serve as the access point:


public IQueryable<MultiStatementTest> MultiStatements(int p1) => FromExpression(() => MultiStatements(p1));

Where the registration looks like:

modelBuilder.HasDbFunction(typeof(AltDbContext).GetMethod(nameof(MultiStatements), new[] { typeof(int) }))
    .HasName("fn_multi_statement_test");

Then when accessing the values:

    using var context = new AltDbContext();
    var items = context.MultiStatements(2).ToList();

This would return the two multi-statement objects from the results of the function, both with the Id of "2".

Note that there is no DbSet for these function provided entities, they are merely a return type of the defined function.

发布评论

评论列表(0)

  1. 暂无评论