1 回答
TA贡献1825条经验 获得超4个赞
除非您正在使用,否则您SQL-Server 2016没有对JSONin的本机支持MSSQL。
因此,最好的方法是将数据转换为XML,然后将其传递给Stored Procedure,这在应用程序必须将大量数据传递到数据库的情况下最常用。
方法 1将数据作为 xml 传递
为了传递数据,您需要对类定义进行一些更改:
using System.Xml.Serialization;
[XmlRoot(ElementName = "Rootobject")] //defining a root element for the xml
public class Rootobject
{
[XmlElement(ElementName = "recipe")] //defining the name for the serialization
public Recipe[] recipe { get; set; }
[XmlElement(ElementName = "recipeIngredients")]//defining the name for the serialization
public Recipeingredient[] recipeIngredients { get; set; }
}
在上面的代码中,我做了一些更改,我添加了一个XMLRoot来指定 XML 的根元素,并且XmlElement基本上为根元素中的子元素定义一个名称。
现在为了在 asp.net中将数据从javascript(客户端)发送到c#(服务器端),我们必须创建一个static由WebMethod赋予属性的方法(简单来说,它是一种可以从javascript 或 jquery ), 如下:
[WebMethod]
public static string postRootObject(Rootobject roots)
{
try
{
var objectXML = serializeListtoXML<Rootobject>(roots); //converting the given object into an xml string
//passing the data to stored procedure as
var statusSP = sendXMLToSqlServer("readDataFromXML", objectXML);
return "yaaay it works";
}
catch (Exception ex)
{
throw ex;
}
}
然后在方法中,sendXMLToSqlServer(<procedurename>,<xmldata>)我将生成的 xml 字符串传递给过程:
public static bool sendXMLToSqlServer(string procedure,string xmlData)
{
var status = false;
try
{
using (SqlConnection con = new SqlConnection(@"<your connection string goes here>"))
{
con.Open();
var com = new SqlCommand();
com.CommandText = procedure;
com.Connection = con;
com.Parameters.Add(new SqlParameter("@data",xmlData));
com.CommandType = System.Data.CommandType.StoredProcedure;
//i am using the dataAdapter approach to get the data from the procedure you can write your own code to read the output from the procedure
var ds = new DataSet();
var da = new SqlDataAdapter(com);
da.Fill(ds);
if (ds.Tables[0].Rows.Count > 0) //check if there is any record from
status = true;
}
}
catch (Exception ex)
{
throw ex;
}
return status;
}
请注意,上面给出的创建 SQL 连接和执行代码的方法永远不应在表示层项目中,它们应始终位于单独的库中,并且应始终在表示层项目中引用(因此关注点分离),这也可以应用用于业务逻辑代码。
正如您在上面的代码中看到的那样,我有一个名为 as 的存储过程,readDataFromXML其中 1 个参数命名为 as @data,数据类型为 as xml。
现在访问xml在SQL这里边是程序将如何看起来像:
CREATE PROCEDURE readdatafromxml @data XML
AS
BEGIN
SELECT r.rc.value('(RecipeContributor/text())[1]', 'varchar(100)') AS
contributor,
r.rc.value('(RecipeDifficulty/text())[1]', 'varchar(100)') AS
difficulty,
r.rc.value('(RecipeRating/text())[1]', 'varchar(100)') AS
rating,
r.rc.value('(RecipeInstructions/text())[1]', 'varchar(100)') AS
instructions,
r.rc.value('(RecipeName/text())[1]', 'varchar(100)') AS
NAME,
r.rc.value('(RecipePrepTime/text())[1]', 'varchar(100)') AS
preptime,
r.rc.value('(RecipeCookTime/text())[1]', 'varchar(100)') AS
cooktime,
r.rc.value('(ImageURL/text())[1]', 'varchar(100)') AS
imgurl,
r.rc.value('(RecipeProtein/text())[1]', 'varchar(100)') AS
protien,
r.rc.value('(RecipeFats/text())[1]', 'varchar(100)') AS
fats,
r.rc.value('(RecipeCarbs/text())[1]', 'varchar(100)') AS
carbs
,
r.rc.value('(RecipeFiber/text())[1]', 'varchar(100)')
AS fiber,
r.rc.value('(RecipeDescription/text())[1]', 'varchar(100)') AS
reciepdescription
INTO #tmprecipe
FROM @data.nodes('/Rootobject/recipe') AS r(rc)
SELECT r.ri.value('(IngredientListQuanity/text())[1]', 'varchar(100)') AS
quantity,
r.ri.value('(MeasurementSizeName/text())[1]', 'varchar(100)') AS
sizename,
r.ri.value('(IngredientName/text())[1]', 'varchar(100)') AS
ingredientname
INTO #tmprecipeingrident
FROM @data.nodes('/Rootobject/recipeIngredients') AS r(ri)
--i am using a simple select just to check if there is some data in the temporary table you can change the code to match your need.
SELECT *
FROM #tmprecipe;
SELECT *
FROM #tmprecipeingrident;
--clearing the memory by dropping the temporary tables
DROP TABLE #tmprecipeingrident;
DROP TABLE #tmprecipe;
END
在上面,stored procedure我将数据从 传递xml到临时表并从xmlas访问它:
FROM @data.nodes('/Rootobject/recipe') AS r(rc)
这是将给定对象转换为XML字符串的代码:
public static string serializeListtoXML<T>(T obj)
{
System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
serializer.Serialize(ms, obj);
ms.Position = 0;
xmlDoc.Load(ms);
return xmlDoc.InnerXml;
}
}
在上面的代码中,我创建了一个XMLDocument将序列化对象传递到该xml文档,然后返回InnerXML该文档的对象。
方法 2将数据作为JSON传递(仅在 SQL-Server 2016 及更高版本中使用)
为了传递JSON给SQL-Server我们必须对上面的代码做一些改变:
xml从Rootobject类中删除属性,然后将方法中的代码更改postRootObject(Rootobject roots)为将数据序列化为JSON字符串,如下所示:
[WebMethod]
public static string postRootObject(Rootobject roots)
{
try
{
var objectJsonString = JsonConvert.SerializeObject(roots);
//pass to stored procedure as
var statusSP = sendJsonToSqlServer("readDataFromJSON", objectJsonString);
return "yaay it works";
}
catch (Exception ex)
{
throw ex;
}
}
在该方法中sendJsonToSqlServer把一切都因为相同的,因为它是sendXMLToSqlServer因为数据是我们派出会有string这情况下是相同的对象XML。现在唯一的改变,你需要在存储过程中,这将是为(使用JSON工作SQL Server 2016):
create procedure readDataFromJSON @data nvarchar(4000)
as
begin
select
contributor,difficulty,rating,instructions,[name],preptime,cooktime,imgurl,protien,fats,carbs,fiber,reciepdescription
into #tmprecipe
from OPENJSON(@data,'$.Rootobject.recipe')
WITH (
RecipeContributor varchar(100) '$.RecipeContributor' as contributor,
RecipeDifficulty varchar(100) '$.RecipeDifficulty' as difficulty,
RecipeRating varchar(100) '$.RecipeRating' as rating,
RecipeInstructions varchar(100) '$.RecipeInstructions' as instructions,
RecipeName varchar(100) '$.RecipeName' as name,
RecipePrepTime varchar(100) '$.RecipePrepTime' as preptime,
RecipeCookTime varchar(100) '$.RecipeCookTime' as cooktime,
ImageURL varchar(100) '$.ImageURL' as imgurl,
RecipeProtein varchar(100) '$.RecipeProtein' as protien,
RecipeFats varchar(100) '$.RecipeFats' as fats,
RecipeCarbs varchar(100) '$.RecipeCarbs' as carbs,
RecipeFiber varchar(100) '$.RecipeFiber' as fibre,
RecipeDescription varchar(100) '$.RecipeDescription' as reciepdescription,
);
select
quantity,sizename,ingredientname
into #tmprecipeingrident
from OPENJSON(@data,'$.Rootobject.recipeIngredients')
WITH (
IngredientListQuanity varchar(100) '$.IngredientListQuanity' as quantity,
MeasurementSizeName varchar(100) '$.MeasurementSizeName' as sizename,
IngredientName varchar(100) '$.IngredientName' as ingredientname
);
select * from #tmprecipe;
select * from #tmprecipeingrident;
drop table #tmprecipeingrident;
drop table #tmprecipe;
end
注意:上面的代码没有经过测试,因为我没有 SQL-Server 2016。但是根据微软提供的文档,它应该可以进行一些调整(如果这不起作用)。
- 1 回答
- 0 关注
- 224 浏览
添加回答
举报
