Посмотрите на этот пример Plnkr
Переменная this
сильно отличается timesCalled
с каждым нажатием кнопки увеличивается только на 1. Ответ на мой личный вопрос:
.click( () => { } )
и
.click(function() { })
создают одинаковое количество функции при использовании в цикле, как вы можете видеть из подсчета Guid в Plnkr.
Действительно поздно, и я только провел приблизительно 10 минут на это, таким образом, ее чрезвычайно неаккуратное, однако это действительно работает и даст Вам хорошую стартовую точку:
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace TableGenerator
{
class Program
{
static void Main(string[] args)
{
List<TableClass> tables = new List<TableClass>();
// Pass assembly name via argument
Assembly a = Assembly.LoadFile(args[0]);
Type[] types = a.GetTypes();
// Get Types in the assembly.
foreach (Type t in types)
{
TableClass tc = new TableClass(t);
tables.Add(tc);
}
// Create SQL for each table
foreach (TableClass table in tables)
{
Console.WriteLine(table.CreateTableScript());
Console.WriteLine();
}
// Total Hacked way to find FK relationships! Too lazy to fix right now
foreach (TableClass table in tables)
{
foreach (KeyValuePair<String, Type> field in table.Fields)
{
foreach (TableClass t2 in tables)
{
if (field.Value.Name == t2.ClassName)
{
// We have a FK Relationship!
Console.WriteLine("GO");
Console.WriteLine("ALTER TABLE " + table.ClassName + " WITH NOCHECK");
Console.WriteLine("ADD CONSTRAINT FK_" + field.Key + " FOREIGN KEY (" + field.Key + ") REFERENCES " + t2.ClassName + "(ID)");
Console.WriteLine("GO");
}
}
}
}
}
}
public class TableClass
{
private List<KeyValuePair<String, Type>> _fieldInfo = new List<KeyValuePair<String, Type>>();
private string _className = String.Empty;
private Dictionary<Type, String> dataMapper
{
get
{
// Add the rest of your CLR Types to SQL Types mapping here
Dictionary<Type, String> dataMapper = new Dictionary<Type, string>();
dataMapper.Add(typeof(int), "BIGINT");
dataMapper.Add(typeof(string), "NVARCHAR(500)");
dataMapper.Add(typeof(bool), "BIT");
dataMapper.Add(typeof(DateTime), "DATETIME");
dataMapper.Add(typeof(float), "FLOAT");
dataMapper.Add(typeof(decimal), "DECIMAL(18,0)");
dataMapper.Add(typeof(Guid), "UNIQUEIDENTIFIER");
return dataMapper;
}
}
public List<KeyValuePair<String, Type>> Fields
{
get { return this._fieldInfo; }
set { this._fieldInfo = value; }
}
public string ClassName
{
get { return this._className; }
set { this._className = value; }
}
public TableClass(Type t)
{
this._className = t.Name;
foreach (PropertyInfo p in t.GetProperties())
{
KeyValuePair<String, Type> field = new KeyValuePair<String, Type>(p.Name, p.PropertyType);
this.Fields.Add(field);
}
}
public string CreateTableScript()
{
System.Text.StringBuilder script = new StringBuilder();
script.AppendLine("CREATE TABLE " + this.ClassName);
script.AppendLine("(");
script.AppendLine("\t ID BIGINT,");
for (int i = 0; i < this.Fields.Count; i++)
{
KeyValuePair<String, Type> field = this.Fields[i];
if (dataMapper.ContainsKey(field.Value))
{
script.Append("\t " + field.Key + " " + dataMapper[field.Value]);
}
else
{
// Complex Type?
script.Append("\t " + field.Key + " BIGINT");
}
if (i != this.Fields.Count - 1)
{
script.Append(",");
}
script.Append(Environment.NewLine);
}
script.AppendLine(")");
return script.ToString();
}
}
}
я поместил эти классы в блок для тестирования его:
public class FakeDataClass
{
public int AnInt
{
get;
set;
}
public string AString
{
get;
set;
}
public float AFloat
{
get;
set;
}
public FKClass AFKReference
{
get;
set;
}
}
public class FKClass
{
public int AFKInt
{
get;
set;
}
}
И это генерировало следующий SQL:
CREATE TABLE FakeDataClass
(
ID BIGINT,
AnInt BIGINT,
AString NVARCHAR(255),
AFloat FLOAT,
AFKReference BIGINT
)
CREATE TABLE FKClass
(
ID BIGINT,
AFKInt BIGINT
)
GO
ALTER TABLE FakeDataClass WITH NOCHECK
ADD CONSTRAINT FK_AFKReference FOREIGN KEY (AFKReference) REFERENCES FKClass(ID)
GO
Некоторые дальнейшие размышления... Я рассмотрел бы добавление атрибута, такого как [SqlTable] к Вашим классам, тот способ, которым это только генерирует таблицы для классов, которые Вы хотите. Кроме того, это может быть очищено, тонна, исправленные ошибки, оптимизировала (Средство проверки FK является шуткой), и т.д. и т.д... Только запустить Вас.
@Jonathan Голландия
, Ничего себе, я думаю, что это - самая необработанная работа, которую я когда-либо видел помещенный в сообщение StackOverflow.Ай да молодец. Однако , вместо того, чтобы создать операторы DDL как строки, необходимо определенно использовать Объекты управления SQL Server классы, начатые с SQL 2005.
у David Hayden есть сообщение, наделенное правом , Составляют Таблицу в SQL Server 2005 Используя C# и Объекты управления SQL Server (SMO) - Генерация кода , который идет через, как составить таблицу с помощью SMO. Объекты со строгим контролем типов делают его бризом с методами как:
// Create new table, called TestTable
Table newTable = new Table(db, "TestTable");
и
// Create a PK Index for the table
Index index = new Index(newTable, "PK_TestTable");
index.IndexKeyType = IndexKeyType.DriPrimaryKey;
VanOrman при использовании SQL 2005 определенно делают часть SMO решения.
Я думаю для сложных типов данных, необходимо расширить их путем определения ToDB () метод, который содержит их собственную реализацию для того, чтобы составить таблицы в DB и этот способ, которым это становится авторекурсивным.
Для составных типов можно рекурсивно преобразовать каждого, что Вы сталкиваетесь в собственную таблицу и затем пытаетесь управлять отношениями внешнего ключа.
можно также хотеть предварительно определить , который классы будут или не преобразовываться в таблицы. Что касается сложных данных, которые Вы хотите отраженный в базе данных, не чрезмерно увеличивая размер схемы, у Вас может быть одна или несколько таблиц для разных типов. Этот пример использует целых 4:
CREATE TABLE MiscTypes /* may have to include standard types as well */
( TypeID INT,
TypeName VARCHAR(...)
)
CREATE TABLE MiscProperties
( PropertyID INT,
DeclaringTypeID INT, /* FK to MiscTypes */
PropertyName VARCHAR(...),
ValueTypeID INT /* FK to MiscTypes */
)
CREATE TABLE MiscData
( ObjectID INT,
TypeID INT
)
CREATE TABLE MiscValues
( ObjectID INT, /* FK to MiscData*/
PropertyID INT,
Value VARCHAR(...)
)
Также..., возможно, можно использовать некоторый инструмент, такой как Visio (не уверенный, если Visio делает это, но я думаю, что это делает) перепроектировать классы в UML и затем использовать UML, чтобы генерировать Схему DB... или возможно использовать инструмент, такой как этот http://www.tangiblearchitect.net/visual-studio/
Я знаю, что Вы ищете весь слой персистентности, но hbm2ddl задача NHIBERNATE может сделать это почти как остроту.
существует задача NAnt, доступная для вызова его, который может представлять интерес.
Дозвуковой также другая опция. Я часто использую его для генерации классов объекта, которые отображаются на базу данных. Это имеет утилиту командной строки, которая позволяет Вам определить таблицы, типы и хост других полезных вещей
Попробуйте DaoliteMappingTool за .net. Это может помочь Вам генерировать классы. Загрузите форму Здесь
Вы можете сделать противоположную таблицу базы данных для классов C # здесь: http://pureobjects.com/dbCode.aspx