• 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。
  • 相关阅读:
    【 SSH 配置参考】
    【 SSH 实例】使用ssh开发的简单项目
    【 Hibernate 】Hibernate的session更新和删除失败问题
    【 SSH 整合】Spring、Struts、Hibernate基本整合
    Tower是个不错的项目管理开放平台
    随便写写,四年多了第一次在博客园上发表
    asp.net获取服务器绝对路径和相对路径
    342. 4的幂
    283. 移动零
    268. 缺失数字
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/1766041.html
Copyright © 2020-2023  润新知