ORM data access framework for a class GraphQL release

Zongsoft.Data announcement

We are pleased that our  ORM data access framework ( Zongsoft.Data ) in over two SaaS after application products, today announced the promotion of foreign!
This is a class  GraphQL  style  the ORM ( O bject / R & lt elational  M apping) data access frame.

And a wheel?

A very long time, the .NET camp seems to have been the lack of a commonly used ORM data access framework, from the earliest native  ADO.NET to exotic iBatis.NET and Hibernate.NET , and later went through  Linq for SQL  and  E ntity F ramework melee, probably because E ntity F fuzzy positioning ramework and repeated an earlier version of the design changes led to the loss of its position of supremacy, thus creating a period of constant progress, warlords total by the Warring States period. After long and repeated over expectations, disappointment, tangled and pain, I finally decided to create a hands-on wheels.

design concept

Before You Get Started, first determine the following basic design principles:

  • Priority Database ( D ATA B ASE F. IRST)
  • Strict POCO / POJO support
  • Mapping model and the code completely isolated
  • Prohibit business layer appears  SQL and class  SQL Code

In a business system, the data structure and its relationship undoubtedly the most basic structure of the underlying database developed by the system architect or person in charge carefully designed ( N O S Chema / W is Eakly S Trend is applied honey Chema poison) , data access mapping database table structure to the relationship as the cornerstone of the business layer on top of this conceptual mapping model drawn up as the yardstick, isolation between levels.

Avoid domain model entities by annotating (label) to metadata definition, should ensure strict compliance with POCO / POJO paradigm. By semantic S to declare the relationship data structure access Chema, prohibiting the application layer  SQL and Linq  formula based SQL  code may reduce dependence on the data layer, the business layer, to enhance the maintainability, but also have more uniform controllable convenience, and provides greater freedom to optimize space and data access engine.

Examples show

The following by way of example three (Note: examples are based Zongsoft.Community item) to substantiate the upper part of the design concept, and examples set forth more Refer Zongsoft.Data  project README.md  documents and  Zongsoft.Community Code Project.

Note: The following examples are based on Zongsoft.Community open source project, which is a complete community forum daemon. You may need to read it in advance of the project "database table structure design" document, in order to better understand the business logic code example.

Examples of a

Navigation and navigation filter query

var forums = this.DataAccess.Select<Forum>(
    Condition.Equal("SiteId", this.User.SiteId) &
    Condition.In("Visibility", Visibility.Internal, Visibility.Public) |
    (
        Condition.Equal("Visibility", Visibility.Specified) &
        Condition.Exists("Users",
                  Condition.Equal("UserId", this.User.UserId) &
                  (
                      Condition.Equal("IsModerator", true) |
                      Condition.NotEqual("Permission", Permission.None)
                  )
        )
    ),
    "*, MostRecentThread{ThreadId,Title,Creator{Name,Nickname,Avatar}}"
);

The above data access query methods generally generate the following SQL script:

SELECT
    t.*,
    t1.ThreadId AS 'MostRecentThread.ThreadId',
    t1.Title AS 'MostRecentThread.Title',
    t1.CreatorId AS 'MostRecentThread.CreatorId',
    t2.UserId AS 'MostRecentThread.Creator.UserId',
    t2.Name AS 'MostRecentThread.Creator.Name',
    t2.Nickname AS 'MostRecentThread.Creator.Nickname',
    t2.Avatar AS 'MostRecentThread.Creator.Avatar'
FROM Forum t
    LEFT JOIN Thread AS t1 ON
        t.MostRecentThreadId=t1.ThreadId
    LEFT JOIN UserProfile AS t2 ON
        t1.CreatorId=t2.UserId
WHERE
    t.SiteId = @p1 AND
    t.Visibility IN (@p2, @p3) OR
    (
        t.Visibility = @p4 AND
        EXISTS
        (
            SELECT u.SiteId, u.ForumId, u.UserId
            FROM ForumUser u
            WHERE u.SiteId = t.SiteId AND
                  u.ForumId = t.ForumId AND
                  u.UserId = @p5 AND
                  (
                      u.IsModerator = @p6 OR
                      u.Permission != @p7
                  )
        )
    );

By the above-described exemplary  Select query process schema parameters (i.e., the value of  *, MostRecentThread{ThreadId,Title,Creator{Name,Nickname,Avatar}} the parameter) specifies the hierarchical relationships between data and query data in the form, eliminating the need for  SQL or class SQL syntax  JOIN syntax elements such as imperative, which not only provides a more simple and semantic API access, and returned to the underlying data access engine optimization provides greater space and freedom.

If the  Select query method schema parameter values changed *,Moderators{*},MostRecentThread{ThreadId,Title,Creator{Name,Nickname,Avatar}} after the data access engine will be broken down into many internal inquiry of two SQL statements iterative execution, and these do not need the business layer spin-off process, which increases efficiency and reduces the complexity of the business layer.

Note: The S Chema mode expression by W eb API  available to front-end applications, will greatly reduce the workload of back-end development, enhance the efficiency of front and rear ends.

Example Two

Many of the new association

// 构建待新增的实体对象
var forum = new
{
    SiteId = this.User.SiteId,
    GroupId = 100,
    Name = "xxxx",

    // 一对多的导航属性
    Users = new ForumUser[]
    {
      new ForumUser { UserId = 1001, IsModerator = true },
      new ForumUser { UserId = 1002, Permission = Permission.Read },
      new ForumUser { UserId = 1003, Permission = Permission.Write },
    }
}

// 执行数据新增操作
this.DataAccess.Insert<Forum>(forum, "*, Users{*}");

Add said data access method substantially generate the following SQL script:

/* 主表插入语句,执行一次 */
INSERT INTO Forum (SiteId,ForumId,GroupId,Name,...) VALUES (@p1,@p2,@p3,@p4,...);

/* 子表插入语句,执行多次 */
INSERT INTO ForumUser (SiteId,ForumId,UserId,Permission,IsModerator) VALUES (@p1,@p2,@p3,@p4,@p5);

By the above-described exemplary Insert new process  schema parameters (i.e., the value of *,User{*} the specified parameters) the shape of the new data by the data access engine according to the automatic processing mapping definition underlying SQL implementation, to ensure simplicity and higher layer service code efficiency .

Example Three

And one-to-many association update for the "many" navigation properties, but also to ensure the attribute value (collection) to  UPSERT  write mode.

public bool Approve(ulong threadId)
{
    //构建更新的条件
    var criteria =
        Condition.Equal(nameof(Thread.ThreadId), threadId) &
        Condition.Equal(nameof(Thread.Approved), false) &
        Condition.Equal(nameof(Thread.SiteId), this.User.SiteId) &
        Condition.Exists("Forum.Users",
            Condition.Equal(nameof(Forum.ForumUser.UserId), this.User.UserId) &
            Condition.Equal(nameof(Forum.ForumUser.IsModerator), true));

    //执行数据更新操作
    return this.DataAccess.Update<Thread>(new
    {
        Approved = true,
        ApprovedTime = DateTime.Now,
        Post = new
        {
            Approved = true,
        }
    }, criteria, "*,Post{Approved}") > 0;
}

Updating said data access method substantially generate the following SQL script:

/* 以下代码为支持 OUTPUT/RETURNING 子句的数据库(如:SQLServer,Oracle,PostgreSQL) */

/* 根据更新的关联键创建临时表 */
CREATE TABLE #TMP
(
    PostId bigint NOT NULL
);

/* 更新主表,并将更新的关联键输出到内存临时表 */
UPDATE T SET
    T.[Approved]=@p1,
    T.[ApprovedTime]=@p2
OUTPUT DELETED.PostId INTO #TMP
FROM [Community_Thread] AS T
    LEFT JOIN [Community_Forum] AS T1 ON /* Forum */
        T1.[SiteId]=T.[SiteId] AND
        T1.[ForumId]=T.[ForumId]
WHERE
    T.[ThreadId]=@p3 AND
    T.[Approved]=@p4 AND
    T.[SiteId]=@p5 AND EXISTS (
        SELECT [SiteId],[ForumId]
        FROM [Community_ForumUser]
        WHERE [SiteId]=T1.[SiteId] AND
              [ForumId]=T1.[ForumId] AND
              [UserId]=@p6 AND
              [IsModerator]=@p7
    );

/* 更新关联表 */
UPDATE T SET
    T.[Approved]=@p1
FROM [Community_Post] AS T
WHERE EXISTS (
    SELECT [PostId]
    FROM #TMP
    WHERE [PostId]=T.[PostId]);

By the above-described exemplary Update updated process schemaparameters (i.e., the value of *,Post{Approved} the specified parameter) of the shape data updating, efficient data access engine according to the generated database type SQL statements for all the service layer is no sense of transparency.

For many of the navigation attributes, data access engine will default UPSERT  mode processing written subset, about UPSERT  more information, please refer Zongsoft.Data  project documentation.

performance

We want to provide the best overall value for money for a  ORM data access engine, the performance of major concern (not) these elements:

  1. Simple and efficient generation of SQL scripts, and as far as possible using the latest database-specific SQL syntax;
  2. Data query result entity assembly ( P opulate) process must be efficient;
  3. Avoid reflections, valid syntax tree cache.

We used to achieve the level of E mitting dynamic compiler technology on the real assembly ( P opulate), and other data binding parameters for preheating, available  DataPopulator source code and other related classes in-depth understanding.

other

Thanks to the "Statement way to express the data structure of relations" semantic design concept, with respect to the order in terms of design, it makes the program more focused intent, naturally express the underlying data and optimize more tolerance and freedom.

More detailed information (for example: separate read and write, inheritance table, data pattern, map files, filters, validators, type conversion, data isolation) , please refer to the relevant documents.

Support Sponsors

We welcome and look forward to any kind of promotional support!

If you agree with our design concept for this project, please point like ( S tar), if you think the project is useful and want to support its future development, please give the necessary funds to support it:

  1. Watch Zongsoft micro-channel public number , our article carried a reward;
  2. Join Zongsoft knowledge planet ring , available online quiz and technical support;
  3. If your business requires on-site technical support and counseling, or need to develop new features, bug fixes, etc. Please immediately send an email to me.

Well micro channel number

Knowledge Planet


Reminder: This article may be updated, please read the original: http://zongsoft.com/blog/zh-cn/zongsoft/announcing-data-engine , in order to avoid error caused due to stale content, but also a better reading experience.

Guess you like

Origin www.cnblogs.com/Zongsoft/p/announcing-data-engine.html