Why did you write it?
Why write? Probably sunk costs.
It's just that since Source Generators came out, I've been planning to use it to see if I could do aop (now that it has built-in functionality), and I originally wanted to try to see if I could do something with orm back then, but unfortunately for various reasons, I've forgotten about that intention.
It wasn't until July of this year that the intention came back to me, and now that the energy isn't working, and I was supposed to be done with studying the principles and functional limitations.
But it's been quite a while since I wrote it, and it felt like a bit of a waste not to write it in full, and it took quite a bit more time to put something likeDapperAOT Functionality is pretty much done
After writing and feel that the light copy copy function is not interesting, so the previous in order to write some less repetitive code in the company to do the query customization function in the base to get a hand, anyway, the cost has been spent so much!
While this isn't much of an innovation, it's an idea that's been around for a long time, with the most dramatic being graphql, which even made it necessary to build everyone's infrastructure, it's also an idea that's been around for a long time, and it's been around for a long time.
But more and more, all the way to the Fourth of July, so far can only be regarded as the main body is completed, there are still a lot of details have not been done!
A lot of conversions Parsing is handwritten, not because of the writing of nb, just the introduction of other libraries compatible with may be a bit of a problem, the scene is not much, recursive traversal is enough!
I don't have time to mess with nuget or anything else, there are quite a few bugs, so I'll mess with it later when it's more complete, it's all for my own amusement anyway.
I'm getting older. I'm getting slower and slower.
what can I do?
1. db mapping to entities
look as ifDapperAOT As with the use ofSource Generators Generate the necessary code during the build to help you use sql more easily.
Theoretically, you can also performNative AOT Deployment
It's nothing really. Give me a chestnut.
public async Task<object> OldWay()
{
var a = ();
using var dd = await ("""
SELECT count(1)
FROM Weather;
SELECT *
FROM Weather;
""");
var t = await <int>();
var r = await <string>().ToListAsync();
return new { TotalCount = t, Rows = r };
}
2. Make query coding simple and support more complex conditions
By defining some simple query rules, we can convert a query into a db / api / es query statement ....
Currently, I've only done the db conversion, and I haven't had time to do the full adaptation test, es, mongodb, etc. I'll have time to do that later.
In theory, though, we could do this:
http query string / body |------> select statement |------> db (sqlite / mysql/ sqlserver / PostgreSQL)
Expression code |------> |------> es
|------> mongodb
|------> more .....
interlocutoryselect statement
The layer's defined, the front end's converted, the back end's theorized and adapted, and anything can be done.
2.1 An api example
Code exmples:
First, define an entity configuration that lists which fields can be looked up, sorted, and filtered.
[Db("Demo")]
[Table(nameof(Weather))]
public class Weather
{
[Select, Where, OrderBy]
public string Name { get; set; }
[Select(Field = "Value as v"), Where, OrderBy]
public string V { get; set; }
[Select(NotAllow = true)]
public string Test { get; set; }
}
Then define the query interface
[HttpGet]
public async Task<object> Selects() // You can do some of the fields yourself, authorization check [FromQuery, Required] string name)
{
return await <Weather>();
}
Then you can let the users spell out various conditions for them to fulfill their own scenarios, so you can touch the fish yourself for a little while longer
curl --location 'http://localhost:5259/weather?where=not (name like '%e%')&TotalCount=true'
Response
{
"totalCount": 1,
"rows": [
{
"name": "H",
"v": "mery!"
}
]
}
2.2 The same can be done to make the query code simpler
Code exmples:
In fact, many orm's offer the ability to use Expression to achieve similar or more complex results.
Here to consider the workload, restful api and other data query implementation support degree is not the same, at present only do the basic filter support, join what do not engage in, even if you engage in more than half of them will be scolded, directly write the sql is not better?
for example, the following query Weather which name no Contains 'e'
public async Task<object> DoSelects()
{
return await (<Weather>().Where(i => !("e")).WithTotalCount());
}
Here is a very simple introduction, complex, how to realize the not write, tired, can not write, to have an interest in gayhub can look at the source code/fs7744/
Here's another list of filter operator support
Query in api
Both has func support use query string or body to query
body or query string will map to Dictionary<string, string>
to handle
operater
such filter operater just make api more restful (Where=urlencode(complex condition)
will be more better)
-
{{nl}}
is null- query string
?name={{nl}}
- body
{"name":"{{nl}}"}
- query string
-
{{eq}}
Equal =- query string
?name=xxx
- body
{"name":"xxx"}
- query string
-
{{lt}}
LessThan or Equal <=- query string
?age={{lt}}30
- body
{"age":"{{lt}}30"}
- query string
-
{{le}}
LessThan <- query string
?age={{le}}30
- body
{"age":"{{le}}30"}
- query string
-
{{gt}}
GreaterThan or Equal >=- query string
?age={{gt}}30
- body
{"age":"{{gt}}30"}
- query string
-
{{gr}}
GreaterThan >- query string
?age={{gr}}30
- body
{"age":"{{gr}}30"}
- query string
-
{{nq}}
Not Equal !=- query string
?age={{nq}}30
- body
{"age":"{{nq}}30"}
- query string
-
{{lk}}
Prefix Like 'e%'- query string
?name={{lk}}e
- body
{"name":"{{lk}}e"}
- query string
-
{{rk}}
Suffix Like '%e'- query string
?name={{rk}}e
- body
{"name":"{{rk}}e"}
- query string
-
{{kk}}
Like '%e%'- query string
?name={{kk}}e
- body
{"name":"{{kk}}e"}
- query string
-
{{in}}
in array (bool/number/string)- query string
?name={{in}}[true,false]
- body
{"name":"{{in}}[\"s\",\"sky\"]"}
- query string
-
{{no}}
not- query string
?age={{no}}{{lt}}30
- body
{"age":"{{no}}{{lt}}30"}
- query string
Func Fields:
-
Fields
return some Fields , no Fields orFields=*
is return all- query string
?Fields=name,age
- body
{"Fields":"name,age"}
- query string
-
TotalCount
return total count- query string
?TotalCount=true
- body
{"TotalCount":"true"}
- query string
-
NoRows
no return rows- query string
?NoRows=true
- body
{"NoRows":"true"}
- query string
-
Offset
Offset Rows index- query string
?Offset=10
- body
{"Offset":10}
- query string
-
Rows
Take Rows count, default is 10- query string
?Rows=100
- body
{"Rows":100}
- query string
-
OrderBy
sort result- query string
?OrderBy=name:asc,age:desc
- body
{"OrderBy":"name:asc,age:desc"}
- query string
-
Where
complex condition filter- query string
?Where=urlencode( not(name like 'H%') or name like '%v%' )
- body
{"Where":"not(name like 'H%') or name like '%v%'"}
- operaters
- bool
- example
true
orfalse
- example
- number
- example
12323
or1.324
or-44.4
- example
- string
- example
'sdsdfa'
or'sds\'dfa'
or"dsdsdsd"
or"fs\"dsf"
- example
-
= null
is null- example
name = null
- example
-
=
Equal- example
name = 'sky'
- example
-
<=
LessThan or Equal- example
age <= 30
- example
-
<
LessThan- example
age < 30
- example
-
>=
GreaterThan or Equal- example
age >= 30
- example
-
>
GreaterThan- example
age > 30
- example
-
!=
Not Equal- example
age != 30
- example
-
like 'e%'
Prefix Like- example
name like 'xx%'
- example
-
like '%e'
Suffix Like- example
name like '%xx'
- example
-
like '%e%'
Like- example
name like '%xx%'
- example
-
in ()
in array (bool/number/string)- example
in (1,2,3)
orin ('sdsdfa','sdfa')
orin (true,false)
- example
-
not
- example
not( age <= 30 )
- example
-
and
- example
age <= 30 and age > 60
- example
-
or
- example
age <= 30 or age > 60
- example
-
()
- example
(age <= 30 or age > 60) and name = 'killer'
- example
- bool
- query string