C# EF Core 3 DBFunction IQueryable返回类型
有人知道在efcore中使用DBFunction声明是否可以返回除标量值以外的任何值吗 我正在使用SQL Server将一个站点从EF6迁移到EFCore v3.1.1(从.Net Framework 4.7.2迁移到.Net Core 3.0)。SQL函数有一个两列的表类型返回值。e、 g.(这是实际案例的简化版本): 在EF6模型中,有一个DBFunction声明,返回一个IQueryable,其中ReturnModel是POCO(即,不是映射表实体): 使用声明为C# EF Core 3 DBFunction IQueryable返回类型,c#,entity-framework,dbfunctions,C#,Entity Framework,Dbfunctions,有人知道在efcore中使用DBFunction声明是否可以返回除标量值以外的任何值吗 我正在使用SQL Server将一个站点从EF6迁移到EFCore v3.1.1(从.Net Framework 4.7.2迁移到.Net Core 3.0)。SQL函数有一个两列的表类型返回值。e、 g.(这是实际案例的简化版本): 在EF6模型中,有一个DBFunction声明,返回一个IQueryable,其中ReturnModel是POCO(即,不是映射表实体): 使用声明为 [DbFunction(
[DbFunction("fn_getValues")]
public virtual IQueryable<ReturnModel> fn_getValues(Nullable<int> tenantId, Nullable<int> dataItemId) {
var tenantIdParameter = tenantId.HasValue ?
new ObjectParameter("tenantId", tenantId) :
new ObjectParameter("tenantId", typeof(int));
var dataItemIdParameter = dataItemId.HasValue ?
new ObjectParameter("dataItemId", dataItemId) :
new ObjectParameter("dataItemId", typeof(int));
return ((IObjectContextAdapter)this).ObjectContext
.CreateQuery<ReturnModel>("[dbo].[fn_getValues](@tenantId, @dataItemId)", tenantId, dataItemId);
}
[DbFunction(“fn_getValues”)]
公共虚拟IQueryable fn_getValues(可为null的tenantId、可为null的dataItemId){
var tenantId参数=tenantId.HasValue?
新的ObjectParameter(“tenantId”,tenantId):
新的ObjectParameter(“tenantId”,typeof(int));
var dataItemIdParameter=dataItemId.HasValue?
新的ObjectParameter(“dataItemId”,dataItemId):
新的ObjectParameter(“dataItemId”,typeof(int));
返回((IObjectContextAdapter)this).ObjectContext
.CreateQuery(“[dbo].[fn_getValues](@tenantId,@dataItemId)”,tenantId,dataItemId);
}
但我不能让它在EF Core 3中工作。我已尝试将返回类型声明为无键实体,并将DBFunction重新映射到:
[DbFunction("fn_getValues")]
public virtual IQueryable<ReturnModel> fn_getValues(Nullable<int> tenantId, Nullable<int> dataItemId) {
throw new NotSupportedException();
}
[DbFunction(“fn_getValues”)]
公共虚拟IQueryable fn_getValues(可为null的tenantId、可为null的dataItemId){
抛出新的NotSupportedException();
}
下面是一个如何在愤怒中使用的例子:
int tenantId = <something>;
int filterItemId = <something>;
using (var db = new DBContext) {
var query = from a in db.ParentItems
where a.filterItem = filterItemId
select new {
a.Id,
a.Name,
ModelValues = db.fn_getValues(tenantId, a.Id)
};
return await query.ToListAsync();
}
inttenantid=;
int filterItemId=;
使用(var db=new DBContext){
var query=来自db.ParentItems中的
其中a.filterItem=filterItemId
选择新的{
a、 身份证,
a、 名字,
ModelValues=db.fn\u getValues(tenantId,a.Id)
};
return wait query.ToListAsync();
}
这总是导致抛出错误
The DbFunction 'fn_getValues' has an invalid return type 'IQueryable<ReturnModel>'. Ensure that the return type can be mapped by the current provider.
DbFunction“fn_getValues”的返回类型“IQueryable”无效。确保返回类型可以由当前提供程序映射。
是否可以从EF Core3返回复杂类型,或者我需要做一些可怕的事情,比如用分隔符将数据字段合并成一个字符串值,并在响应中拆分它们?EF Core中对TVFs的支持不同,但有一个补偿功能。您可以使用原始SQL查询组合其他LINQ查询表达式:
var searchTerm = ".NET";
var blogs = context.Blogs
.FromSqlInterpolated($"SELECT * FROM dbo.SearchBlogs({searchTerm})")
.Where(b => b.Rating > 3)
.OrderByDescending(b => b.Rating)
.ToList();
返回一个
IQueryable
,您可以从fn\u getValues
返回该属性(省略DbFunctionAttribute)。EF Core中对TVFs的支持不同,但有一个补偿功能。您可以使用原始SQL查询组合其他LINQ查询表达式:
var searchTerm = ".NET";
var blogs = context.Blogs
.FromSqlInterpolated($"SELECT * FROM dbo.SearchBlogs({searchTerm})")
.Where(b => b.Rating > 3)
.OrderByDescending(b => b.Rating)
.ToList();
返回一个可从
fn\u getValues
返回的IQueryable
(省略DbFunctionAttribute)。谢谢David。是的,我使用“FromSqlInterpolated”成功地获取了数据,但在尝试将其中一个参数作为字段从联接表中传递时却没有。我必须首先返回结果集,然后使用FromSqlInterpolated方法对其进行迭代以获得每个子集合。这是预期的方法/行为吗?是。如果没有对TVFs的一流支持,EF将无法生成应用程序以将外部查询列传递给TVF。谢谢David。是的,我使用“FromSqlInterpolated”成功地获取了数据,但在尝试将其中一个参数作为字段从联接表中传递时却没有。我必须首先返回结果集,然后使用FromSqlInterpolated方法对其进行迭代以获得每个子集合。这是预期的方法/行为吗?是。如果没有对TVFs的第一类支持,EF将无法生成应用程序以将外部查询列传递给TVF。
var searchTerm = ".NET";
var blogs = context.Blogs
.FromSqlInterpolated($"SELECT * FROM dbo.SearchBlogs({searchTerm})")
.Where(b => b.Rating > 3)
.OrderByDescending(b => b.Rating)
.ToList();