首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将C#嵌套对象保存到SQL server的有效方法

将C#嵌套对象保存到SQL server的有效方法
EN

Stack Overflow用户
提问于 2014-09-15 07:33:41
回答 2查看 3.5K关注 0票数 5

我有一个表结构,它嵌套到5个层次,一个到多个关系向下。我想知道将这种数据保存到Server中的有效方法是什么。我现在循环每个子对象(C#)并运行一个insert,如果数据很大,插入就会变慢。

在传统的C#中是否有一种直接将ADO.NET传递给ADO.NET的方法?我有一个自定义框架,它为每个insert触发一个SQL脚本,它从对象属性中获取值。我不能转移到EF或NHirbernate,因为这是一个现有的项目。

我已经看到了将C#对象插入到DataTables中然后传递给SQl的方法,这是一种有效的方法吗?

请给我建议。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-15 08:10:24

我假设您从数据库的角度来看有这样的东西

代码语言:javascript
复制
CREATE TABLE Items (ID INT -- primary key, 
                    Name VARCHAR(MAX),
                    ParentID INT) -- foreign key that loops on the same table

在C#中有一个这样的对象

代码语言:javascript
复制
public class Item
{
   public int ID {get; set;}
   public string Name {get; set;}
   public int ParentID {get; set;}
   public Item Parent {get; set;}
   public List<Item> Children {get; set;}
}

你有一些代码看起来是:

代码语言:javascript
复制
var root = MakeMeATree();
databaseSaver.SaveToDatabase(root);

为每个子项目生成一个插入项。如果你有很多孩子,这真的可以减缓应用程序的速度。

在这种情况下,我将使用(并且已经使用)一个自定义sql服务器类型和一个存储过程来将整个事件保存在一个调用中。

您需要创建一个与表匹配的类型:

代码语言:javascript
复制
CREATE TYPE dbo.ItemType AS TABLE
(
    ID INT,
    Name VARCHAR(MAX),
    ParentID INT
);

以及使用以下类型的简单过程:

代码语言:javascript
复制
CREATE PROCEDURE dbo.InsertItems
(
  @Items AS dbo.ItemType READONLY
)
AS
BEGIN
  INSERT INTO SampleTable(ID, Name, ParentID)
  SELECT ID, Name, ParentID From @Items
END

现在,这是从Server端执行的。现在转到C#侧。你需要做两件事:

  1. 将层次结构扁平化为列表
  2. 将该列表作为datatable发送到数据库

第一种方法可以使用类似于的东西(我使用,这基本上是相同的),只需一个简单的

代码语言:javascript
复制
var items = root.Flatten(i => i.Children);

要做第二件事,首先需要将Server类型声明为datatable:

代码语言:javascript
复制
DataTable dt = new DataTable("Items"); 
dt.Columns.Add("ID", typeof(int)); 
dt.Columns.Add("Name", typeof(string)); 
dt.Columns.Add("ParentID", typeof(int)); 

接下来,只需填充以下值:

代码语言:javascript
复制
foreach(var item in items)
{
   dt.Rows.Add(item.ID, item.Name, item.ParentID);
}

并将它们附加到一个应该是SqlParameter类型的SqlDbType.Structured上,如下所示:

代码语言:javascript
复制
using (var cmd = new SqlCommand("InsertItems", connection))
{
    cmd.CommandType = CommandType.StoredProcedure;
    var itemsParam = new SqlParameter("@Items", SqlDbType.Structured);
    itemsParam .Value = dt;

    cmd.Parameters.Add(itemsParam);
    cmd.ExecuteNonQuery();
}

应该是这样的。

票数 6
EN

Stack Overflow用户

发布于 2014-09-15 08:10:09

是的,如果希望将Dataset对象存储在DataBase中,可以使用选项,比如创建一个SQL UserDefinedType对象。在存储过程中填充对象、requierd值和read值,并使用您可以存储在Db中的业务逻辑填充Temp中的对象值。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25842909

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档