代码改变世界

使用 ALinq 支持多种数据库

2010-03-27 11:21  麦舒  阅读(1103)  评论(1编辑  收藏  举报

1、打开设计器,生成实体类,然后在 External Mapping 属性中,选择 true。Connection 属性中的 Application Setting 设为 true, 然后保存重新生成代码,你会发现多了一个后缀名为 .designer.map 的 Xml 文件 。

 

生成 Xml 映射文件(局部)

 

2、在代码中使用 XmlMapping

代码
public Database()
:
base(WebConfigurationManager.ConnectionStrings["ALinqBBS"].ConnectionString, CreateMappingSource())
{

}

public Database(string connn)
:
base(connn, CreateMappingSource())
{

}

static XmlMappingSource CreateMappingSource()
{
var xmlMapping
= XmlMappingSource.FromStream(typeof(Database).Assembly.GetManifestResourceStream("ALinq.BBS.Business.Database.designer.map"));
return xmlMapping;
}

 

3、下面我们接着来把数据库转换成 MS SQL 数据库

 

代码
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
var stream
= typeof(Database).Assembly.GetManifestResourceStream("ALinq.BBS.Business.Database.designer.map");
Debug.Assert(stream
!= null);
var reader
= new System.IO.StreamReader(stream);

//将Provider 切换为 Sql2005Provider
var xmlDatabase = XmlMappingSourceUtility.CreateFrom<Database>(reader);
xmlDatabase.Provider
= "ALinq.SqlClient.Sql2005Provider, ALinq, Version=2.3.0.0, Culture=neutral, PublicKeyToken=2b23f34316d38f3a";

//修改 XmlMapping 中 SQLite 的数据类型为 SQL2005 的数据类型。如果你需要导入数据,并且含还有自增长列,你还得设 DbGenerate 为 false 。
var xmlColumn = xmlDatabase.Type(o => o.Posts).Column(o => o.Content);
xmlColumn.DbType
= "Text";

xmlColumn
= xmlDatabase.Type(o => o.Replies).Column(o => o.Content);
xmlColumn.DbType
= "Text";

//下面的是 SQL2005 数据库
var conn = @"Data Source=VPC1\SQLEXPRESS;Initial Catalog=ALinqBBS;User ID=sa;Password=test";
var db
= new Database(conn, XmlMappingSource.FromXml(xmlDatabase.Element.ToString())) { Log = Console.Out };

var sqlLiteDb
= new Database(@"C:\ALinqBBS.db3", XmlMappingSource.FromStream(typeof(Database).Assembly.GetManifestResourceStream("ALinq.BBS.Business.Database.designer.map"))) { Log = Console.Out };

//如查你不需要导入数据库,直接生成数据库就可以了。代码如下:
//if (db.DatabaseExists())
// db.DeleteDatabase();
//db.CreateDatabase();

//如查你需要导入数据库,请参考下面的代码。
var tables = db.Mapping.GetTables();
foreach (var table in tables)
{


//在数据库中创建表
if (db.TableExists(table))
db.DeleteTable(table);

db.CreateTable(table);
}

//导入数据库 开始
foreach (var board in sqlLiteDb.Boards.ToList())
db.Boards.Insert(board);

foreach (var post in sqlLiteDb.Posts.ToList())
db.Posts.Insert(post);

foreach (var reply in sqlLiteDb.Replies.ToList())
db.Replies.Insert(reply);

foreach (var user in sqlLiteDb.Users.ToList())
{
var date
= DateTime.Parse("1900-1-1");
if (user.CreationDate < date)
user.CreationDate
= date;

db.Users.Insert(user);
}

foreach (var topPost in sqlLiteDb.TopPosts.ToList())
db.TopPosts.Insert(topPost);

foreach (var item in sqlLiteDb.PostFavors)
db.PostFavors.Insert(item);

foreach (var item in sqlLiteDb.ObjectIdentities)
db.ObjectIdentities.Insert(item);

//导入数据库 结束

//创建关联
foreach (var table in tables)
{
db.CreateForeignKeys(table);
}

}
}

class XMappingDatabase<T>
{
public XMappingDatabase(XElement element)
{
this.Element = element;
}

public XElement Element { get; private set; }

public string Provider
{
get
{
var attribute
= Element.Attribute("Provider");
if (attribute == null)
return null;
return attribute.Value;
}
set
{
var attribute
= Element.Attribute("Provider");
if (attribute == null)
Element.SetAttributeValue(
"Provider", value);
else
attribute.Value
= value;
}
}
}

class XMappingType<T>
{
public XMappingType(XElement element)
{
this.Element = element;
}

public XElement Element { get; private set; }
}

class XMappingColumn
{
public XMappingColumn(XElement element)
{
this.Element = element;
}

public XElement Element { get; private set; }

public string DbType
{
get
{
var attribute
= Element.Attribute("DbType");
if (attribute == null)
return null;
return attribute.Value;
}
set
{
var attribute
= Element.Attribute("DbType");
if (attribute == null)
Element.SetAttributeValue(
"DbType", value);
else
attribute.Value
= value;
}
}
}

static class XmlMappingSourceUtility
{
public static XMappingType<TEntity> Type<TSource, TEntity>(this XMappingDatabase<TSource> source, Expression<Func<TSource, Table<TEntity>>> predicate) where TEntity : class
{
var name
= typeof(TEntity).FullName;

var element
= source.Element.Descendants().Where(o => o.Name.LocalName == "Type")
.Where(o
=> o.Attribute("Name") != null && o.Attribute("Name").Value == name).SingleOrDefault();
if (element == null)
throw new Exception(string.Format("Count Not Found the '{0}' Element in the XDocument", name));

return new XMappingType<TEntity>(element);
}

public static XMappingColumn Column<TSource>(this XMappingType<TSource> source, Expression<Func<TSource, object>> predicate)
{
var parameters
= predicate.Parameters;
var name
= ((MemberExpression)predicate.Body).Member.Name;

var element
= source.Element.Descendants().Where(o => o.Name.LocalName == "Column")
.Where(o
=> o.Attribute("Name") != null && o.Attribute("Name").Value == name).SingleOrDefault();
if (element == null)
throw new Exception(string.Format("Count Not Found the '{0}' Element in the XDocument", name));

return new XMappingColumn(element);
}

public static XMappingDatabase<TSource> CreateFrom<TSource>(StreamReader reader)
{
var doc
= XElement.Load(reader, LoadOptions.None);
return new XMappingDatabase<TSource>(doc);
}

}

}