我在现场有一个软件,我需要向它添加一个新表。我的实体框架中有表格,新客户得到表格。我如何更新其他人?
补充:为了明确我的发展和新客户有桌子。如何更新旧客户数据库是个问题?
因为它在我的模型中,所以我似乎应该调用一个 create 方法,一切都应该在幕后发生。
_context.NewTable.CreateTable();
但是认为我将不得不编写一个 sql 命令字符串来查看表是否存在以及是否不创建表。
IDVisitorEntities _context = new IDVisitorEntities ();
String cmd = IF NOT EXISTS ( SELECT [name]
FROM sys.tables
WHERE [name] = NewTable )
CREATE TABLE NewTable (
ID int IDENITY,
NAME VARCHAR(40))
_context.NewTable.CommandText (cmd);
如果表不存在,我只想运行一次。所以这并不能解决这个问题。我真的不知道该怎么办。
2013 年 5 月 6 日添加 我认为 EF 对每个表都有属性集合,这可能有一个线索。可能必须使用 ICustomTypeDescriptor ...其他人有什么想法吗?
添加于 2013 年 7 月15 日 我开始构建它,在我的新工作中,这里是一个示例。我需要使用部分类创建一个文件,并将抽象和接口应用于它们。它还有很长的路要走,但这是一个开始......
namespace DataModelMAXFM
{
public abstract class ATable
{
private ArrayList _columns = new ArrayList();
private ArrayList colsToAdd = new ArrayList();
public ArrayList Columns
{
get
{
return _columns;
}
}
public bool TableCreate(SqlConnection sqlConn)
{
//assuming table needs to be created (already checked)
//get column list
//use for loop to create query string
// run command
ITable thisItable;
if (Columns.Count <= 0) //generate column list if not already created
{
if (!ColumnList())
return false;
}
if (this is ITable)
{
thisItable = (ITable) this;
}
else
{
throw new Exception("");
}
StringBuilder sb = new StringBuilder("CREATE TABLE " + thisItable.GetTableName() + " (");
bool flgFirst = true; // to allow for proper comma placement
foreach (PropertyInfo prop in Columns)
{
String propType = this.GetDataType(prop);
if (propType == String.Empty)//check to make sure datatype found a match, EF to SQL
{
return false;
}
if (!flgFirst)
{
sb.Append(", ");
}
else
{
flgFirst = false;
}
sb.Append(prop.Name + " " + propType);
}
// add right parentheses
sb.Append(")");
//now run query created above
SqlCommand com;
try
{
com = new SqlCommand(sb.ToString(), sqlConn);
com.ExecuteNonQuery();
}
catch (Exception e)
{
Console.WriteLine("TableCreate e:" + e.ToString());
return false;
}
return true;
}
public bool TableExists(SqlConnection sqlConn)
{
SqlDataReader sdr = null;
SqlCommand com;
ITable thisItable;
try
{
//create and execute command
if (this is ITable)
thisItable = (ITable)this;
else
{
throw new Exception("");
}
com = new SqlCommand("Select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = " + thisItable.GetTableName(), sqlConn);
sdr = com.ExecuteReader();
if (!sdr.HasRows)//ie table does not exist
{
return false;
}
}
catch (Exception e)
{
Console.WriteLine("TableCreate e:" + e.ToString());
return false;
}
//close datareader
try
{
sdr.Close();
}
catch (Exception e)
{
Console.WriteLine("close sqldatareader TableExists e: " + e.ToString());
}
return true;
}
public bool ColumnList()
{
bool flgListCreated = false;
PropertyInfo[] propList = typeof(TransactionCategory).GetProperties();
foreach (PropertyInfo prop in propList)
{
if (prop.CanRead && prop.CanWrite)
{
MethodInfo mget = prop.GetGetMethod(false);
MethodInfo mset = prop.GetSetMethod(false);
// Get and set methods have to be public
if (mget == null)
{
continue;
}
if (mset == null)
{
continue;
}
Columns.Add(prop);
if (!flgListCreated)
{
flgListCreated = true;
}
}
}
return flgListCreated;
}
public bool ColumnsExist(SqlConnection sqlConn)
{
ITable thisItable;
if (Columns.Count <= 0)
{
if (!ColumnList())
return false;
}
//2013-07-10 create basic connection and data reader
if (this is ITable)
thisItable = (ITable)this;
else
{
throw new Exception("");
}
SqlDataReader sdr = null;
SqlCommand com;
foreach (PropertyInfo prop in Columns)
{
try
{
//create and execute command
com = new SqlCommand("Select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = " + thisItable.GetTableName() + " and COLUMN_NAME = " + prop.Name, sqlConn);
sdr = com.ExecuteReader();
//if no rows returned to datareader == column does not exist, add to ArrayList of columns to add
if (!sdr.HasRows)
colsToAdd.Add(prop);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return false;
}
}
//close datareader
try
{
sdr.Close();
}
catch (Exception e)
{
Console.WriteLine("close sqldatareader ColumnsExist e: " + e.ToString());
}
if (colsToAdd.Count == 0)
return false;
//returns true only if method worked and found columns to add to DB
return true;
}
public bool ColumnsCreate(SqlConnection sqlConn)
{
ITable thisItable;
StringBuilder sb = new StringBuilder();
if (colsToAdd.Count <= 0)
{
if (!ColumnsExist(sqlConn)) //2013-07-08 - MAXIMUS\58398(BJH) //if no columns, attempt to create list
return false; // if Column list was not created, return false
}
// add a array of the alter table
if (this is ITable)
thisItable = (ITable)this;
else
{
throw new Exception();
}
sb.Append("ALTER TABLE " + thisItable.GetTableName() + " ADD ( ");
bool flgFirst = true; // allows for no leading comma on first entry
String propType;
foreach (PropertyInfo prop in colsToAdd)
{
//make sure SQL datatype can be determined from EF data
propType = this.GetDataType(prop);
if (propType == String.Empty)
throw new Exception("no datatype match found " + prop.Name + " " + prop.PropertyType.ToString());
if (!flgFirst)
{
sb.Append(", ");
}
else
{
flgFirst = false;
}
sb.Append(prop.Name + " " + propType);
}
sb.Append(" )");
SqlCommand com;
try
{
com = new SqlCommand(sb.ToString(), sqlConn);
com.ExecuteNonQuery();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return false;
}
return true;
}
public bool ColumnsUpdate(SqlConnection sqlConn)
{
if (ColumnsExist(sqlConn))
return ColumnsCreate(sqlConn);
else
return false;
}
//method to convert from EF to SQL datatypes, see noted issues
public String GetDataType(PropertyInfo pi)
{
String s = "";
String pistr = pi.PropertyType.ToString();
switch (pistr)
{
case "Byte[]":
s = "binary";
break;
case "Boolean":
s = "bit";
break;
case "String Char[]": // also maps to other options such as nchar, ntext, nvarchar, text, varchar
s = "char";
break;
case "DateTime":
s = "datetime";
break;
case "DateTimeOffset":
s = "datetimeoffset";
break;
case "Decimal":
s = "decimal";
break;
case "Double":
s = "float";
break;
case "Int16":
s = "smallint";
break;
case "Int32":
s = "int";
break;
case "Int64":
s = "bigint";
break;
case "Single":
s = "real";
break;
case "TimeSpan":
s = "time";
break;
case "Byte":
s = "tinyint";
break;
case "Guid":
s = "uniqueidentifier";
break;
case "Xml":
s = "xml";
break;
default:
Console.WriteLine("No datatype match found for " + pi.ToString() + " " + pi.PropertyType.ToString());
return String.Empty;
}
return s;
}
}
public interface ITable
{
int ID
{
get;
}
bool TableUpdate(SqlConnection sqlConn);
bool TableStoredProceduresCreate(SqlConnection sqlConn);
bool TableStoredProceduresDrop(SqlConnection sqlConn);
bool TableCreateTriggers(SqlConnection sqlConn);
bool TableCreateViews(SqlConnection sqlConn);
DataTable GetDataTable();
DateTime dtTableImplemented
{
get;
}
String GetTableName();
}
}