如何使用 EF fluent api 将 sql 服务器上的用户定义类型映射到模型?
How to map user defined type on sql server with EF fluent api to a model?
在 sql 服务器上,我将用户定义的类型设置为这样
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; }
}
我也有一个以这个类型为参数的存储过程,这个过程returns一个sql查询结果table,我想用[=调用这个存储过程29=] 并检索结果。我是这样做的
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 对象才能正确传递我的 Table Valued User Defined Parameters。我创建了一个函数,该函数使用我的模型中的对象列表并返回正确配置的 SqlParameter。
这是我的用户定义参数
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; }
}
我创建了一个模型列表并用数据填充它
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)
在 sql 服务器上,我将用户定义的类型设置为这样
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; }
}
我也有一个以这个类型为参数的存储过程,这个过程returns一个sql查询结果table,我想用[=调用这个存储过程29=] 并检索结果。我是这样做的
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 对象才能正确传递我的 Table Valued User Defined Parameters。我创建了一个函数,该函数使用我的模型中的对象列表并返回正确配置的 SqlParameter。
这是我的用户定义参数
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; }
}
我创建了一个模型列表并用数据填充它
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)