ALinq

这几天,在博客园看到了很多朋友的 ORM,忍不住也把我写的 ORM 拉出来溜溜,我写的这款 ORM 叫 ALinq 。


1、什么是 ALinq ?

ALinq 是一款与 Linq to SQL 相兼容的 ORM。简而言之,就是 Linq to SQL 的山寨版,并且青出于蓝,胜于蓝。它不但完整实现了 Linq to SQL 的功能,并在其基础上进行了一系列的扩展。

API 的改进:

1、支持多种数据库,包括 MSSQL2000,20005,Access,SQLite,MySQL,Oracle,与 Friebird 。

2、更为便利的增删改功能,允许批量更新删除

3、增加了 DataContext.CreateTable, DataContext.CreateForegionKey 函数。这两个函数大大方便了用户在虚拟主机上创建数据库,或者对数据库进导入。

设计器的改进:

1、允许在属性、类中添加 Attribute 特性。这大大方便了用户与第三方框架配合使用。

2、允行在属性、类中添加注释。

3、允许对实体类进行更新,例如:在数据库添加了一个新的字段,只需点一下鼠标,即可刷新。

 4、可以生成 Xml 映射文件。

2、为什么要使用 ALinq ,而不是第三方 ORM  ?

1、ALinq 拥用完善的设计器,与 Linq to SQL 相兼容的 API ,你无重新学习,即可上手。只要你安装好,即可懂得用了,所有 Linq to SQL 的知识都可以迁移到 ALinq 上。

2、ALinq 运行效率高,品质稳定,并且已经经过大量的用户验证,好评如潮,我们的用户遍及各行各业。

3、ALinq 是收费,收费也会成为使用的理由 ??? 是的,因为 ALinq 能收到钱,所以可以一直更新维护下去。相信我,ALinq 是绝对是款性价比极高的软件。买东西,我们都知道,可不能一味追求便宜。其实软件也是这样,免费、开源的东西,用在项目里,绝对会让人发狂。你可能会说,拥有代码,碰到问题可以自行修改,这只不过是理论上的罢了,实际上绝大部份的人都是不可能做到的,不信你把 DBLinq 里的 BUG 都给修正,事实 ALinq 有很多用户都是从 DBLinq 转过来的。

 

3、发展线路图

* 增强对 Ado.net data service 增、删、改操作的支持。

* ALinq:支持 HQL 或 ESQL 查询。

* ALinq:支持多表继承与以及多对多关联。

* ORDesigner:实现从模型更新数据库。

* ORDesigner:集成数据库设计。

* ORDesigner:集成数据验证的代码生成。

* ORDesigner:Ado.net data service 代码生成。

* ORDesigner:支持 Visual Studio 2010。

ALinq 可以秒杀 Linq to SQL, Entity Framework ? 你是不是觉得我在吹牛呢?是驴是马,拉出溜溜就知道。

请各位看官到 http://cn.alinq.org 下载试用,好不好用,你来评价。如果你下载了,发现不好用,尽管来踢场好了。

使用 ALinq 支持多种数据库

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

}

}

[ORDesigner] 自动编号属性的设置

选择要设置为自动编号的属性,例如:UserID。然后将 Auto Generated 设置为 true,Auto-Sync 设置为 OnInsert

ALinq -- Linq to Access,SQLite,MySQL,Oracle,Firebird。

[ORDesigner] 自定义数据库连接自符串

很多时候,我们都需要从配置文件中读取数据库连接自符串,但是 ORDesigner 生成 DataContext 的初始化函数是写死的。

public MyDataContext(ALinq.Mapping.MappingSource mappingSource) :
base("data source=C:\\Northwind.db", mappingSource)
{
OnCreated();
}

其实我们只要设置一下就行了,就不会生成上面的初始化函数了。将 Application Settings 由 false 改为 true 。

ALinq -- Linq to Access,SQLite,MySQL,Oracle,Firebird。

ALinq(V2.2) 双主键关联 Bug(已修正)

这个 Bug 已经修正,但尚未发布,急需用的可以和我联系。

Is possible to create association EntitySet with multiple primary keys?

See the example:

Order

IdCompany

PK

IdOrder

PK

Number

Sum

OrderDetail

IdCompany

FK

IdOrder

FK

IdDetail

PK

Qtde

PriceUnit

Sum

I did search on google in linq to sql references and not found something about.

I tried do the code:

[Association(Name = "ORDER_DETAILS", Storage = "_Details", ThisKey = "IdCompany,IdOrder", OtherKey = "IdCompany,IdOrder")]

Can you help me? (I have a license)

ALinq -- Linq to Access,SQLite,MySQL,Oracle,Firebird。
原文地址:https://www.cnblogs.com/Leo_wl/p/1766041.html