根据用户输入为插入创建动态数量的参数

时间:2014-11-23 08:39:29

标签: sql asp.net sql-server

我在3层架构中构建我的应用程序。在我的DataAccess类中,我得到了一个将Person插入数据库的函数。

Person表在数据库中最多包含81列。用户最初可能不会在这些列中插入所有数据,因此他可能只填充10或20个字段。

有没有办法可以让Insert类中的DataAccess函数接受动态参数个数,这样它只会传递那些有数据且不被强制等待81个参数的函数并尝试每次插入81个参数?

3 个答案:

答案 0 :(得分:1)

快速而肮脏的解决方案是传入一个字典,其中包含您要更改的项目的名称和值:

public void Upsert(Dictionary<string, object> KeyValues, Dictionary<string, object> Changes)
{
    // insert logic here
}
PS:请注意,许多ORM为您解决了这个问题,例如go和google Entity Framework。

答案 1 :(得分:1)

为存储过程中的参数指定默认值,这样您就不必从代码中传递所有参数。见下文:

CREATE PROCEDURE USP_PERSON_INSERT  
 @FirstName VARCHAR(100),
 @LastName VARCHAR(100) = NULL
AS 

答案 2 :(得分:0)

编写将行插入单个表的sproc时,一个非常好的选择是使用Table-Valued Parameters

首先,您需要创建一个table type来反映您要插入新记录的表格,例如

CREATE TYPE dbo.PersonType AS TABLE
    ( PersonID int, LastName nvarchar(50), FirstName nvarchar(50), ... etc )

然后,使用此表类型,您可以编写一个接受基于该类型的表值参数的sproc,例如:

CREATE PROCEDURE dbo.usp_InsertPerson (@tvpNewPersons dbo.PersonType READONLY)
AS 
BEGIN
    INSERT INTO Person (PersonID, LastName, FirstName)
    SELECT PersonID, LastName, FirstName
    FROM @tvpNewPersons
END

一旦您拥有此基础架构,您就可以将参数传递给Insert单个参数DataAccess方法,即强类型DataTable反映了真正的sql表(顺便说一句,你甚至可以manually create这样的DataTable)。

这就是Insert方法的样子:

public void Insert(PersonDataTable dtPersons)
{

   // ... build connection object here with 'using' block 

   // Create command that executes stored procedure
   SqlCommand command = new SqlCommand("usp_InsertPerson", connection);
   command.CommandType = System.Data.CommandType.StoredProcedure;            

   SqlParameter tvpParameter = command.Parameters.AddWithValue("@tvpNewPersons", dtPersons);
   tvpParameter.SqlDbType = SqlDbType.Structured;

   // now execute command, etc ...
}

PersonDataTable是您需要创建的类型化数据表的类型。