c# - 如何使用EF fluent api将sql server上的用户定义类型映射到模型?
问题描述
在 sql server 上,我制作了这样的用户定义类型
CREATE TYPE [TowarType] AS TABLE(
[GIDTyp] [int] NULL,
[GIDNumer] [int] NULL,
[Kod] [varchar](255) NULL
)
在 c# 中,它由模型表示
public class TowaryType
{
public int GIDTyp { get; set; }
public int GIDNumer { get; set; }
public string Kod { get; set; }
}
我还有一个以这种类型为参数的存储过程,这个过程返回一个sql查询结果表,我想用实体框架调用这个存储过程并检索结果。我这样做
public List<ReturnModelType> GetResultFromSqlQuery<ReturnModelType>(string sqlQuery, params object[] parameters)
{
var result = this.Database.SqlQuery(typeof(ReturnModelType), sqlQuery, parameters);
List<ReturnModelType> localModels = new List<ReturnModelType>();
foreach (var o in result)
{
ReturnModelType m = (ReturnModelType)o;
localModels.Add(m);
}
return localModels;
}
//
var result = _context.GetResultFromSqlQuery<ResultModel>(
"exec StanTowarow @Magazyny, @Towary, @Dzien",
new SqlParameter("@Magazyny", magazynyParams),
new SqlParameter("@Towary", towaryParams),
new SqlParameter("@Dzien", dzien)
);
但我得到 System.ArgumentException,它说我的用户定义类型不存在映射。
我认为你应该用流畅的 API 映射它,但我不知道如何,谁能指出我正确的方向?
解决方案
经过一番阅读,我设法解决了我的问题。我的问题是需要正确配置的 SqlParameter 对象来正确传递我的表值用户定义参数。我创建了一个函数,它使用我的模型中的对象列表并返回一个正确配置的 SqlParameter。
这是我的用户定义参数
CREATE TYPE [TowarType] AS TABLE(
[GIDTyp] [int] NULL,
[GIDNumer] [int] NULL,
[Kod] [varchar](255) NULL
)
// 这里是这个参数的ac#模型
public class TowaryType
{
public int GIDTyp { get; set; }
public int GIDNumer { get; set; }
public string Kod { get; set; }
}
我创建了一个模型列表并用数据填充它
List<TowaryType> modelList = new List<TowaryType>();
//populating code here
之后我需要从该列表中创建一个 SqlParameter ,所以我在我的 applicationDbContext 中创建了一个方法来为我做这件事:
public SqlParameter GetTableValuedParameter<Model>(List<Model> valueTable, string typeName, string paramName)
{
if(valueTable == null || valueTable.Count == 0)
throw new Exception("Cant be empty or null.");
DataTable dataTable = new DataTable();
var header = valueTable.First().GetType().GetProperties();
foreach (var propertyInfo in header)
{
dataTable.Columns.Add(propertyInfo.Name);
}
foreach (var model in valueTable)
{
DataRow dataRow = dataTable.NewRow();
var properties = model.GetType().GetProperties();
foreach (var propertyInfo in properties)
{
dataRow[propertyInfo.Name] = propertyInfo.GetValue(model);
}
dataTable.Rows.Add(dataRow);
}
var sqlParameter = new SqlParameter(paramName, SqlDbType.Structured);
sqlParameter.Value = dataTable;
sqlParameter.TypeName = typeName;
return sqlParameter;
}
之后我所要做的就是在我想要传递给我的存储过程的模型列表上调用这个函数,然后调用我的存储过程
var param1 = _context.GetTableValuedParameter(magazynyParams, "MagazynType", "@Magazyny");
var param2 = _context.GetTableValuedParameter(towaryParams, "TowarType", "@Towary");
var result = _context.GetResultFromSqlQuery<ResultModel>(
"exec StanTowarow @Magazyny, @Towary, @Dzien",
param1,
param2,
new SqlParameter("@Dzien", dzien)
推荐阅读
- swift - 当我的应用程序在前台 Swift iOS 上时,是否可以检测到何时显示第 3 方推送通知
- node.js - 运行在 Windows 上为我的树莓派创建的节点 Web 应用程序时出错
- python-3.x - Tkinter 使按钮比预期的要大
- javascript - 如果此 div 中不仅有文本,还有其他 html 节点(跨度、div ...),我如何获取和设置可编辑 div 中的插入符号位置?
- java - 如何验证弹性搜索中特定索引的快照是否正在进行?
- javascript - 视频编码压缩中HTML5视频的Seek函数和Maximum Keyframe Interval
- php - 用于数据检索的 MySQL 或 JSON
- shell - 以表格格式从 shell 发送电子邮件
- scrapy - 存储来自scrapy dupefilter的过滤请求
- next.js - PurgeCSS 不会从 NextJS 项目中删除未使用的 CSS