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 processschema
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 methodschema
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 processschema
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 processschema
parameters (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:
- Simple and efficient generation of SQL scripts, and as far as possible using the latest database-specific SQL syntax;
- Data query result entity assembly ( P opulate) process must be efficient;
- 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:
- Watch Zongsoft micro-channel public number , our article carried a reward;
- Join Zongsoft knowledge planet ring , available online quiz and technical support;
- 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.
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.