gpt4 book ai didi

c# - EF : Passing a table valued parameter to a user-defined function from C#

转载 作者:行者123 更新时间:2023-12-03 16:26:10 26 4
gpt4 key购买 nike

我在 SQL Server 中有一个用户定义的函数,它接受 TVP(表值参数)作为参数。在 EF 中,如何从 C# 调用这样的函数?
我尝试使用方法 ObjectContext.CreateQuery<>但出现以下错误:

The parameter 'param' of function 'QueryByParam' is invalid. Parameters can only be of a type that can be converted to an Edm scalar type.


也试过方法 ObjectContext.ExecuteStoreQuery<>并得到同样的错误。它不会返回 IQueryable反正。
示例代码
[DbFunction(nameof(SampleDbContext), "QueryByParam")]
public IQueryable<SecurityQueryRow> QueryByParam(IEnumerable<ProfileType> profiles, bool isActive = false)
{
DataTable dataTable = ....
ObjectParameter profilesParam = new ObjectParameter("profileTypeIds", dataTable);

ObjectParameter isActiveParam = new ObjectParameter("isActive ", isActive);

return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<SecurityQueryRow>(
string.Format("[{0}].[{1}](@profileTypeIds, @isActive)", GetType().Name, "QueryByParam"),
profilesParam,
isActiveParam);
}
要求是我们需要一个 IQueryable 返回,而不是消耗的结果。

最佳答案

您可以使用 Raw Sql en EF Core、EF6 中的类似方法来实现,但是您无法获得 IQueryable。下面两个例子。
Entity Framework 核心
将其用作列表过滤器的 SQL 类型:

CREATE TYPE [dbo].[Table1Type] AS TABLE(
[Id] [int] NULL,
[Name] [nchar](10) NULL
)
SQL UDF:
CREATE FUNCTION [dbo].[Func1] 
(
@Ids Table1Type readonly
)
RETURNS TABLE
AS
RETURN
(
SELECT * from Table1 where id in (select Id from @Ids)
)
EF 上下文:
public class MyContext : DbContext
{
public DbSet<Table1> Table1 { get; set; }
}
匹配 sql 类型的 DTO(为简单起见也与 table 相同):
public class Table1
{
public int Id { get; set; }
public string Name { get; set; }
}
示例:
static void Main(string[] args)
{
using (var context = new MyContext())
{
// Declare de Structure filter param
var dt = new DataTable();

DataTable table = new DataTable();
table.Columns.Add(new DataColumn("Id", typeof(int)));
table.Columns.Add(new DataColumn("Name", typeof(string)));
DataRow row = table.NewRow();
row["Id"] = 1;
row["Name"] = "Item";
table.Rows.Add(row);
var param = new SqlParameter("@Ids", table) { TypeName = "dbo.Table1Type", SqlDbType = SqlDbType.Structured };

IQueryable<Table1> query = context.Table1.FromSqlRaw("SELECT * FROM dbo.func1(@Ids)", param);
var result = query.ToList();
}
}
Entity Framework 6
您无法获得 IQueryable,但您可以链接到生成的 IEnumerable。
static void Main(string[] args)
{
using (var context = new MyContext())
{
context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);

// Declare de Structure filter param
var dt = new DataTable();

DataTable table = new DataTable();
table.Columns.Add(new DataColumn("Id", typeof(int)));
table.Columns.Add(new DataColumn("Name", typeof(string)));
DataRow row = table.NewRow();
row["Id"] = 1;
row["Name"] = "Item";
table.Rows.Add(row);
var param = new SqlParameter("@Ids", table) { TypeName = "dbo.Table1Type", SqlDbType = SqlDbType.Structured };

var query = context.Table1.SqlQuery("SELECT * FROM dbo.func1(@Ids)", param);

var result = query.ToList();
}
}

关于c# - EF : Passing a table valued parameter to a user-defined function from C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63742915/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com