我需要生成一个类似下面的XML,其中约束作为标记,列名称作为c#中特定数据库表的值。
<tablename>
<key>ProductId</key>
<composite>
<column>ProductId</column>
<column>ProductCode</column>
<composite>
<ForeignKey>
<column>ProductBaseId</column>
</ForeignKey>
</tablename>
有人可以为此提供帮助吗?
答案 0 :(得分:0)
在这里您可以找到主键:
SELECT Col.Column_Name from
INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab,
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col
WHERE
Col.Constraint_Name = Tab.Constraint_Name
AND Col.Table_Name = Tab.Table_Name
AND Constraint_Type = 'PRIMARY KEY'
AND Col.Table_Name = 'tablename'
如果您有多个PRIMARY KEYS,那么您将从上面的相同查询中获取它们。您可以只计算主键,如果它们大于1,那么您可以在Composite中列出它们。否则只需将它们作为密钥。
这是另一点,如果有两个主键,那么&lt; KEY&gt;中的内容将会是什么?代码
在这里您可以找到外键:
SELECT Col.Column_Name from
INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab,
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col
WHERE
Col.Constraint_Name = Tab.Constraint_Name
AND Col.Table_Name = Tab.Table_Name
AND Constraint_Type = 'FOREIGN KEY'
AND Col.Table_Name = 'tablename'
只需加入两个信息并用XML编写。 XML编写非常简单,您可以在这里找到它。 XML Writing - DotNetPerls
更新1:
这是一个代码,您可以在其中找到pK
和FK
两者以及单个查询中的类型。
SELECT Col.Column_Name,
Case When( CHARINDEX('PK_' , Col.CONSTRAINT_NAME) >0 ) Then 'PK' ELSE 'FK' END as Type
from
INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab,
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col
WHERE
Col.Constraint_Name = Tab.Constraint_Name
AND Col.Table_Name = Tab.Table_Name
AND (Constraint_Type = 'PRIMARY KEY' OR Constraint_Type = 'Foreign KEY')
AND Col.Table_Name = 'table_1'
查询输出如下所示:
Column_Name Type
AnotherID FK
Code PK
ID PK
我知道它并不好,我正在提供充分的代码。但是对我来说很有意思,我写了一些可能对其他人有用的内容。
以下是完整代码:
namespace XMLWritingFromDB
{
public class Program
{
public static string connectionstring = "Data Source=RAHIMPC\\SQLEXPRESS;Initial Catalog=Test;Integrated Security=false;uid=******;pwd=********";
public static SqlConnection conn;
static void Main(string[] args)
{
//Get the table Informations
DataTable dt = GetDataSchema("table_1"); // PUT YOUR TABLE NAME HERE.
string xmlDocument = PrepareXml(dt);
Console.Write(xmlDocument);
Console.ReadKey();
}
public static DataTable GetDataSchema(string TableName)
{
DataTable dt = new DataTable();
string query = "SELECT Col.Column_Name, Case When( CHARINDEX('PK_' , Col.CONSTRAINT_NAME) >0 ) Then 'PK' ELSE 'FK' END as Type " +
" from INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab, INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col " +
" WHERE Col.Constraint_Name = Tab.Constraint_Name AND Col.Table_Name = Tab.Table_Name " +
"AND (Constraint_Type = 'PRIMARY KEY' OR Constraint_Type = 'Foreign KEY') AND Col.Table_Name = '"+TableName+"'";
using (conn = new SqlConnection(connectionstring))
{
conn.Open();
using (SqlCommand sc = new SqlCommand(query, conn))
{
using (SqlDataReader dr = sc.ExecuteReader())
{
dt.Load(dr);
}
}
conn.Close();
}
return dt;
}
public static string PrepareXml(DataTable dt)
{
int pkCount = 0, fkCount = 0;
List<string> lstPK = new List<string>();
List<string> lstFK = new List<string>();
//Build data for xml
foreach (DataRow dr in dt.Rows)
{
if (dr[1].ToString().Contains("PK"))
{
pkCount++;
lstPK.Add(dr[0].ToString());
}
if (dr[1].ToString().Contains("FK"))
{
fkCount++;
lstFK.Add(dr[0].ToString());
}
}
List<TableName> lstXml = new List<TableName>();
TableName xml = new TableName();
xml.key = lstPK[lstPK.Count() - 1].ToString();
xml.ForeignKey = lstFK;
if (pkCount > 1)
xml.Composite = lstPK;
var stringwriter = new System.IO.StringWriter();
var serializer = new XmlSerializer(xml.GetType());
serializer.Serialize(stringwriter, xml);
return stringwriter.ToString();
}
}
[XmlRoot("TableName")]
public class TableName
{
public string key { get; set; }
[XmlArray(ElementName = "Composite")]
[XmlArrayItem("ColumnName", Type = typeof(string))]
public List<string> Composite { get; set; }
[XmlArray(ElementName = "ForeignKey")]
[XmlArrayItem("ColumnName", Type = typeof(string))]
public List<string> ForeignKey { get; set; }
}
}
答案 1 :(得分:0)
您可以使用dataTableObject.WriteXml()
方法,此方法包含各种重载。