前言
项目中一般分测试环境(qas),生产环境(prd),当我们的项目经历了一次周期跨度较长的更新后,当我们发布到生产环境时,首要的任务是将新增的表,字段更新到生产数据库。很多时候,当我们发布更新的时候,已经很难记得做了哪些变更。
当然有的人会说,1.ef code first 有history记录,这是一种办法,可靠么?不可靠。相信即便是用code first,直接改数据库的肯定不止我一个。
2.查看实体类变更记录,这也是一个办法。那如果用的db first的呢?当然也可以看,就是很麻烦。
3.开发过程中,对数据库的变更记下来。这么做过的肯定也不止我一个。手动狗头
。。。。。
中午的时候,就想着另外一个项目下个月要更新,改了n多的东西,到时候数据库咋更新呢。就想着写个工具比较两个版本数据库,表名称,字段,字段类型的区别。
说干就干(本来想着用ef,dbcontext应该可以实现,无奈学艺不精,最终还是回到了ado.net)。
控制台应用程序,目前只能对比新增,修改(sql server)。
using system;
using system.collections.generic;
using system.data.sqlclient;
using system.linq;
using system.text;
using microsoft.entityframeworkcore;
namespace efgettable
{
class program
{
static void main(string[] args)
{
string prdconnectionstring = "data source=localhost;initial catalog=ttprd;user id=sa;password=password;multipleactiveresultsets=true";
var prd = gettablenames(prdconnectionstring);
string qasconnectionstring = "data source=localhost;initial catalog=ttqas;user id=sa;password=password;multipleactiveresultsets=true";
var qas = gettablenames(qasconnectionstring);
comparetable(prd, qas);
}
public static list<tableinfo> gettablenames(string connectionstr)
{
var tableresult = new list<tableinfo>();
string sqltablename = "select * from information_schema.tables";
using (sqlconnection connection = new sqlconnection(connectionstr))
{
using (sqlcommand cmd = new sqlcommand(sqltablename, connection))
{
try
{
connection.open();
sqldatareader dr = cmd.executereader();//
while (dr.read())
{
// 表名
tableinfo table = new tableinfo();
table.tablename = dr["table_name"].tostring();
table.columns.addrange(getcolumnnamesbytable(dr["table_name"].tostring(), connection));
tableresult.add(table);
}
connection.close();
}
catch (system.data.sqlclient.sqlexception e)
{
console.foregroundcolor = consolecolor.red;
console.error.writeline(e.message);
connection.close();
}
}
return tableresult;
}
}
public static list<cloumninfo> getcolumnnamesbytable(string tablename, sqlconnection connection)
{
var columnresults = new list<cloumninfo>();
string sqlcolum = $"select * from information_schema.columns t where t.table_name =\'{tablename}\'";
using (sqlcommand cmd = new sqlcommand(sqlcolum, connection))
{
sqldatareader dr = cmd.executereader();//
while (dr.read())
{
// 表名
cloumninfo column = new cloumninfo();
column.cloumnname = dr["column_name"].tostring();
column.datetype = dr["data_type"].tostring() + dr["character_maximum_length"].tostring();
columnresults.add(column);
}
return columnresults;
}
}
public static void comparetable(list<tableinfo> prd, list<tableinfo> qas)
{
foreach (var p in qas)
{
var tablequery = prd.asqueryable().where(t => t.tablename.equals(p.tablename));
if (!tablequery.any())
{
console.writeline($"new created table {p.tablename}");
continue;
}
else
{
var querytable = tablequery.firstordefault();
p.columns.foreach(c =>
{
var cloumnquery = querytable.columns.select(cc => cc.cloumnname).contains(c.cloumnname);
if (!cloumnquery)
{
console.writeline($"new add cloumn: {c.cloumnname} on table {p.tablename}");
}
else
{
var querycloumn = querytable.columns.where(qt => qt.cloumnname.equals(c.cloumnname)).firstordefault();
if (!querycloumn.datetype.equals(c.datetype))
{
console.writeline($"datetype different: cloumn: {c.cloumnname} , {querycloumn.datetype}==>{c.datetype} on table {p.tablename}");
}
}
});
}
}
}
}
public class tableinfo
{
public tableinfo()
{
columns = new list<cloumninfo>();
}
public string tablename { get; set; }
public list<cloumninfo> columns { get; set; }
}
public class cloumninfo
{
public string cloumnname { get; set; }
public string datetype { get; set; }
}
}
测试结果
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对www.887551.com的支持。