我们的方法(使用 SQL Server 2008 R2)是结合使用表值参数 (TVP) 和合并语句。
这样,代码将项目列表作为表传递给存储过程。然后,proc 在执行插入/更新/删除的合并语句中使用该表。
您需要一个用户定义的表类型,例如:
CREATE TYPE [dbo].[Participants] AS TABLE(
[ProjectId] [int] NOT NULL,
[ParticipantId] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[ProjectId] ASC,
[ParticipantId] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
GO
然后你需要一个 C# 类来保存数据。只需将您的修改IdCollection
为类似于:
public class IdCollection : List<ParticipantUsers>, IEnumerable<SqlDataRecord> {
#region IEnumerable<SqlDataRecord> Members
IEnumerator<SqlDataRecord> IEnumerable<SqlDataRecord>.GetEnumerator() {
SqlDataRecord rec = new SqlDataRecord(
new SqlMetaData("ProjectId", System.Data.SqlDbType.Int),
new SqlMetaData("ParticipantId", System.Data.SqlDbType.Int)
);
foreach (ParticipantUser ans in this) {
rec.SetInt32(0, ans.ProjectId);
rec.SetInt32(1, ans.ParticipantId);
yield return rec;
}
}
#endregion
}
您的存储过程将如下所示:
CREATE PROCEDURE [dbo].[ParticpantUpdate]
@Particpants core.Participants READONLY
AS
BEGIN
SET NOCOUNT ON;
MERGE INTO dbo.ProjectParticipants pp
USING @Particpants RG
ON (RG.ProjectId = pp.ProjectId)
AND (RG.ParticipantId = pp.ParticipantId)
WHEN NOT MATCHED BY TARGET THEN
INSERT( ProjectId, ParticipantId)
VALUES( RG.ProjectId, RG.ParticipantId)
WHEN NOT MATCHED BY SOURCE
AND target.ProjectId in (SELECT ProjectId from @Participants) THEN
DELETE;
;
END
要调用 proc(使用 Enterprise Library):
SqlDatabase db = DatabaseFactory.CreateDatabase("myconnstr") as SqlDatabase;
using ( DbCommand dbCommand = db.GetStoredProcCommand("dbo.ParticipantUpdate") ) {
db.AddInParameter(dbCommand, "Participants", SqlDbType.Structured, participantList);
db.ExecuteNonQuery(dbCommand);
} // using dbCommand