使用 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);
}
}
}