对于给定DB,我使用CodeSmith生成具有以下值的文本文件
(TableName)([TableGUID]) (AttributeName).(AttributeType)
例如
CO_CallSignLists[e3fc5e2d-fe84-492d-ad94-3acced870714] SunSpots.smallint
现在我解析了这些值并将每个值分配给某个变量
for (int j = 0; j < newLst.Count; j += 2)
{
test_objectName_Guid = newLst[j]; //CO_CallSignLists[e3fc5e2d-fe84-492d-ad94-3acced870714]
test_attr = newLst[j + 1]; //SunSpots.smallint
//Seperate Guid from objectName
string[] obNameGuid = test_objectName_Guid.Split('[',']');
var items = from line in obNameGuid
select new
{
aobjectName = obNameGuid[0],
aGuid = obNameGuid[1]
};
foreach (var item in items)
{
final_objectName = item.aobjectName;
final_oGuid = new Guid(item.aGuid);
}
Console.WriteLine("\nFinal ObjectName\t{0}\nFinal Guid\t\t{1}",
final_objectName, final_oGuid);
string final_attributeName = string.Empty;
string final_attributeType = string.Empty;
string[] words = test_attr.Split('.');
var items2 = from line in words
select new
{
attributeName = words[0],
attributeType = words[1]
};
foreach (var item in items2)
{
final_attributeName = item.attributeName;
final_attributeType = item.attributeType;
}
Console.WriteLine("Attribute Name\t\t{0}\nAttributeType\t\t{1}\n",
final_attributeName, final_attributeType);
然后我生成一个xml文件,根据objectName及其GUID从DB加载数据,并将此xml保存在字符串变量中
string generatedXMLFile = Test.run_Load_StoredProcedure(final_objectName, final_oGuid, Dir);
现在我想修改此xml文件中与已解析的txt文件中的属性相等的属性。 (我想根据它的类型修改它)
public void modifyPassedAttribute(string myFile, string attributeName)
{
Object objString = (Object)attributeName;
string strType = string.Empty;
int intType = 0;
XDocument myDoc = XDocument.Load(myFile);
var attrib = myDoc.Descendants().Attributes().Where(a => a.Name.LocalName.Equals(objString));
foreach (XAttribute elem in attrib)
{
Console.WriteLine("ATTRIBUTE NAME IS {0} and of Type {1}", elem, elem.Value.GetType());
if (elem.Value.GetType().Equals(strType.GetType()))
{
elem.Value += "_change";
Console.WriteLine("NEW VALUE IS {0}", elem.Value);
}
else if (elem.Value.GetType().Equals(intType.GetType()))
{
elem.Value += 2;
Console.WriteLine("NEW VALUE IS {0}", elem.Value);
}
}
myDoc.Save(myFile);
}
问题是我总是说值类型是'string'并将其修改为字符串(添加“_change”)..但是当我想将数据保存回数据库时它表示你不能分配nvarchar为smallint值。
我的代码出了什么问题?为什么我总是得到一个字符串类型?是因为所有属性都被视为xml文件中的字符串吗?那我怎么能根据它的原始类型修改属性,这样当我想把它保存回数据库时我不会出错?
我愿意建议优化代码我知道这不是归档目标的最佳代码
修改
以下是生成XML的代码
public void generate_XML_AllTables(string Dir)
{
SqlDataReader Load_SP_List = null; //SQL reader that gets list of stored procedures in the database
SqlDataReader DataclassId = null; //SQL reader to get the DataclassIds from tables
SqlConnection conn = null;
conn = new SqlConnection("Data Source= EUADEVS06\\SS2008;Initial Catalog=TacOps_4_0_0_4_test;integrated security=SSPI; persist security info=False;Trusted_Connection=Yes");
SqlConnection conn_2 = null;
conn_2 = new SqlConnection("Data Source= EUADEVS06\\SS2008;Initial Catalog=TacOps_4_0_0_4_test;integrated security=SSPI; persist security info=False;Trusted_Connection=Yes");
SqlCommand getDataclassId_FromTables;
int num_SP = 0, num_Tables = 0;
string strDataClass; //Name of table
string sql_str; //SQL command to get
conn.Open();
//Select Stored Procedeurs that call upon Tables in the DB. Tables which have multiple DataClassIds (rows)
//Selecting all Load Stored Procedures of CLNT & Get the table names
// to pass the Load operation which generates the XML docs.
SqlCommand cmd = new SqlCommand("Select * from sys.all_objects where type_desc='SQL_STORED_PROCEDURE' and name like 'CLNT%Load';", conn);
Load_SP_List = cmd.ExecuteReader();
while (Load_SP_List.Read())
{
//Gets the list of Stored Procedures, then modifies it
//to get the table names
strDataClass = Load_SP_List[0].ToString();
strDataClass = strDataClass.Replace("CLNT_", "");
strDataClass = strDataClass.Replace("_Load", "");
sql_str = "select TOP 1 DataclassId from " + strDataClass;
conn_2.Open();
getDataclassId_FromTables = new SqlCommand(sql_str, conn_2);
DataclassId = getDataclassId_FromTables.ExecuteReader();
while (DataclassId.Read())
{
string test = DataclassId[0].ToString();
Guid oRootGuid = new Guid(test);
run_Load_StoredProcedure(strDataClass, oRootGuid, Dir);
num_Tables++;
}
DataclassId.Close();
conn_2.Close();
num_SP++;
}
Load_SP_List.Close();
conn.Close();
System.Console.WriteLine("{0} of Stored Procedures have been executed and {1} of XML Files have been generated successfully..", num_SP,num_Tables);
}
public string run_Load_StoredProcedure(string strDataClass, Guid guidRootId, string Dir)
{
SqlDataReader rdr = null;
SqlConnection conn = null;
conn = new SqlConnection("Data Source= EUADEVS06\\SS2008;Initial Catalog=TacOps_4_0_0_4_test;integrated security=SSPI; persist security info=False;Trusted_Connection=Yes");
conn.Open();
// Procedure call with parameters
SqlCommand cmd = new SqlCommand("CLNT_" + strDataClass + "_Load", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 0;
//Adding parameters, in- and output
SqlParameter idParam = new SqlParameter("@DataclassId", SqlDbType.UniqueIdentifier);
idParam.Direction = ParameterDirection.Input;
idParam.Value = guidRootId;
SqlParameter xmlParam = new SqlParameter("@XML", SqlDbType.VarChar, -1 /*MAX*/ );
xmlParam.Direction = ParameterDirection.Output;
cmd.Parameters.Add(idParam);
cmd.Parameters.Add(xmlParam);
rdr = cmd.ExecuteReader(CommandBehavior.SingleResult);
DirectoryInfo dest_2 = new DirectoryInfo(Dir + "\\Copies");
DirectoryInfo dest = new DirectoryInfo(Dir + "\\Backup");
DirectoryInfo source = new DirectoryInfo(Dir);
if (source.Exists == false)
{
source.Create();
if (dest.Exists == false)
{
dest.Create();
}
if (dest_2.Exists == false)
{
dest_2.Create();
}
}
string xmlFile = @Dir + "\\" + strDataClass + " [" + guidRootId + "].xml";
//The value of the output parameter ‘xmlParam’ will be saved in XML format using the StreamWriter.
System.IO.StreamWriter wIn = new System.IO.StreamWriter(xmlFile, false);
wIn.WriteLine(xmlParam.Value.ToString());
wIn.Close();
rdr.Close();
rdr.Close();
conn.Close();
return xmlFile;
}
答案 0 :(得分:0)
简短回答:
是因为所有属性都被视为xml文件中的字符串吗?
是
你需要将原始类型存储在Xml中 - 据我所知,你不包括它,所以你要丢弃这些信息。
答案 1 :(得分:0)
这是修改后的最终代码
public void modifyPassedAttribute(string myFile, string attributeName, string attributeType)
{
Object objString = (Object)attributeName;
string strType = "nvarchar";
string smallintType = "smallint";
string intType = "int";
string dateType = "datetime";
XDocument myDoc = XDocument.Load(myFile);
//var myAttr = from el in myDoc.Root.Elements()
// from attr in el.Attributes()
// where attr.Name.ToString().Equals(attributeName)
// select attr;
var attrib = myDoc.Descendants().Attributes().Where(a => a.Name.LocalName.Equals(objString));
foreach (XAttribute elem in attrib)
{
Console.WriteLine("ATTRIBUTE NAME IS {0} and of Type {1}", elem, elem.Value.GetType());
if (strType.Equals(attributeType))
{
if (elem.Value.EndsWith("_change"))
{
elem.Value = elem.Value.Replace("_change", "");
Console.WriteLine("NEW VALUE IS {0}", elem.Value);
}
else
{
elem.Value += "_change";
Console.WriteLine("NEW VALUE IS {0}", elem.Value);
}
}
else if (smallintType.Equals(attributeType))
{
if (elem.Value.EndsWith("2"))
{
elem.Value = elem.Value.Replace("2", "");
Console.WriteLine("NEW VALUE IS {0}", elem.Value);
}
else
{
elem.Value += 2;
Console.WriteLine("NEW VALUE IS {0}", elem.Value);
}
}
else if (intType.Equals(attributeType))
{
if (elem.Value.EndsWith("2"))
{
elem.Value = elem.Value.Replace("2", "");
Console.WriteLine("NEW VALUE IS {0}", elem.Value);
}
else
{
elem.Value += 2;
Console.WriteLine("NEW VALUE IS {0}", elem.Value);
}
}
else if (dateType.Equals(attributeType))
{
if (elem.Value.EndsWith("2"))
{
elem.Value = elem.Value.Replace("2", "");
Console.WriteLine("NEW VALUE IS {0}", elem.Value);
}
else
{
elem.Value += 2;
Console.WriteLine("NEW VALUE IS {0}", elem.Value);
}
}
}
myDoc.Save(myFile);
}
里面的if语句是这样的,所以不会产生大数字,因为2被添加到字符串100(即1002),如果每次我要加2,那么它就会崩溃