根据数据类型c#修改属性

时间:2010-09-18 09:10:24

标签: c# xml

对于给定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;
    }

2 个答案:

答案 0 :(得分:0)

简短回答:

  

是因为所有属性都被视为xml文件中的字符串吗?

你需要将原始类型存储在Xml中 - 据我所知,你不包括它,所以你要丢弃这些信息。

答案 1 :(得分:0)

好的,所以我解决了这个问题!我所要做的就是将attributeType字符串传递给modifyPassedAttribute函数并使用它来确定我想要做的更改

这是修改后的最终代码

    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,那么它就会崩溃