- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
作者 Mr-zhong 。
代码改变世界.... 。
Fast Framework 基于NET6.0 封装的轻量级 ORM 框架 支持多种数据库 SqlServer Oracle MySql PostgreSql Sqlite 。
优点: 体积小、可动态切换不同实现类库、原生支持微软特性、流畅API、使用简单、性能高、模型数据绑定采用 委托、强大的表达式解析、支持多种子查询可实现较为复杂查询、源代码可读性强.
缺点:目前仅支持Db Frist Code Frist 后续迭代.
开源地址: https://github.com/China-Mr-zhong/Fast-Framework (唯一) 。
框架经受住了生产项目的考验,稳定运行中.
名称 | 说明 |
---|---|
Fast.Framework | 框架主项目 |
Fast.Framework.Logging | 基于微软接口实现的文件日志(非必要可不引用) |
Fast.Framework.Test | 控制台测试项目 |
Fast.Framework.UnitTest | 单元测试项目 |
Fast.Framework.Web.Test | Web测试项目 |
Ado 。
IAdo ado = new AdoProvider(new DbOptions()
{
DbId = "1",
DbType = DbType.MySQL,
ProviderName = "MySqlConnector",
FactoryName = "MySqlConnector.MySqlConnectorFactory,MySqlConnector",
ConnectionStrings = "server=localhost;database=Test;user=root;pwd=123456789;port=3306;min pool size=3;max pool size=100;connect timeout=30;"
});
DbContext 支持多租户 支持切换不同Ado实现类库 设置 ProviderName和FactoryName 即可 。
IDbContext db = new DbContext(new List<DbOptions>() {
new DbOptions()
{
DbId = "1",
DbType = DbType.MySQL,
ProviderName = "MySqlConnector",
FactoryName = "MySqlConnector.MySqlConnectorFactory,MySqlConnector",
ConnectionStrings = "server=localhost;database=Test;user=root;pwd=123456789;port=3306;min pool size=3;max pool size=100;connect timeout=30;"
}});
DbOptions Json文件配置格式 。
"DbOptions": [
{
"DbId": 1,
"DbType": "SQLServer",
"ProviderName": "System.Data.SqlClient",
"FactoryName": "System.Data.SqlClient.SqlClientFactory,System.Data",
"ConnectionStrings": "server=localhost;database=Test;user=sa;pwd=123456789;min pool size=3;max pool size=100;connect timeout=120;"
}]
主从分离(读写分离)配置 。
"DbOptions": [
{
"DbId": 2,
"DbType": "MySQL",
"IsDefault": true,
"ProviderName": "MySqlConnector",
"FactoryName": "MySqlConnector.MySqlConnectorFactory,MySqlConnector",
"ConnectionStrings": "server=localhost;database=Test;user=root;pwd=123456789;port=3306;min pool size=0;max pool size=100;connect timeout=120;AllowLoadLocalInfile=true;",
"UseMasterSlaveSeparation": true,//使用主从分离 注意所有事务将强制走主库
"SlaveItems": [
{
"Weight": 1,//注意多个从库 必须配置权重且总权重>从库数
"ConnectionStrings": "server=localhost;database=Test1;user=root;pwd=123456789;port=3306;min pool size=0;max pool size=100;connect timeout=120;AllowLoadLocalInfile=true;",
"Description": "从库连接配置"
},
{
"Weight": 2,
"ConnectionStrings": "server=localhost;database=Test2;user=root;pwd=123456789;port=3306;min pool size=0;max pool size=100;connect timeout=120;AllowLoadLocalInfile=true;",
"Description": "从库连接配置"
}
],
"Description": "主库连接配置"
}
]
Asp.net Core 依赖注入 。
// 注册服务
var builder = WebApplication.CreateBuilder(args);
// 添加数据库上下文
builder.Services.AddFastDbContext();
// 从Json配置文件加载数据库选项
builder.Services.Configure<List<DbOptions>>(builder.Configuration.GetSection("DbOptions"));
// 产品服务类 通过构造方法注入
public class ProductService
{
/// <summary>
/// 数据库
/// </summary>
private readonly IDbContext db;
/// <summary>
/// 构造方法
/// </summary>
/// <param name="db">数据库</param>
public ProductService(IDbContext db)
{
this.db = db;
}
}
实体对象插入 。
var product = new Product()
{
ProductCode = "1001",
ProductName = "测试商品1"
};
var result = db.Insert(product).Exceute();
Console.WriteLine($"实体对象插入 受影响行数 {result}");
实体对象插入并返回自增ID 仅支持 SQLServer MySQL SQLite 。
var product = new Product()
{
ProductCode = "1001",
ProductName = "测试产品1"
};
var result = db.Insert(product).ExceuteReturnIdentity();
Console.WriteLine($"实体对象插入 返回自增ID {result}");
实体对象列表插入 。
var list = new List<Product>();
for (int i = 0; i < 2100; i++)
{
list.Add(new Product()
{
ProductCode = $"编号{i + 1}",
ProductName = $"名称{i + 1}"
});
}
var result = db.Insert(list).Exceute();
Console.WriteLine($"实体对象列表插入 受影响行数 {result}");
匿名对象插入 。
var obj = new
{
ProductCode = "1001",
ProductName = "测试商品1"
};
//注意:需要使用As方法显示指定表名称
var result = db.Insert(obj).As("Product").Exceute();
Console.WriteLine($"匿名对象插入 受影响行数 {result}");
匿名对象列表插入 。
var list = new List<object>();
for (int i = 0; i < 2100; i++)
{
list.Add(new
{
ProductCode = $"编号{i + 1}",
ProductName = $"名称{i + 1}"
});
}
//注意:需要使用As方法显示指定表名称
var result = db.Insert(list).As("Product").Exceute();
Console.WriteLine($"匿名对象列表插入 受影响行数 {result}");
字典插入 。
var product = new Dictionary<string, object>()
{
{"ProductCode","1001"},
{ "ProductName","测试商品1"}
};
var result = db.Insert(product).As("Product").Exceute();
Console.WriteLine($"字典插入 受影响行数 {result}");
字典列表插入 。
var list = new List<Dictionary<string, object>>();
for (int i = 0; i < 2100; i++)
{
list.Add(new Dictionary<string, object>()
{
{"ProductCode","1001"},
{ "ProductName","测试商品1"}
});
}
var result = db.Insert(list).As("Product").Exceute();
Console.WriteLine($"字典列表插入 受影响行数 {result}");
实体对象删除 。
var product = new Product()
{
ProductId = 1,
ProductCode = "1001",
ProductName = "测试商品1"
};
//注意:必须标记KeyAuttribute特性 否则将抛出异常
var result = db.Delete(product).Exceute();
Console.WriteLine($"实体删除 受影响行数 {result}");
无条件删除 。
var result = db.Delete<Product>().Exceute();
Console.WriteLine($"无条件删除 受影响行数 {result}");
表达式删除 。
var result = await db.Delete<Product>().Where(w => w.ProductId == 1).ExceuteAsync();
Console.WriteLine($"条件删除 受影响行数 {result}");
特殊删除 。
//特殊用法 如需单个条件或多个可搭配 WhereColumn或WhereColumns方法
var result = await db.Delete<object>().As("Product").ExceuteAsync();
Console.WriteLine($"无实体删除 受影响行数 {result}");
实体对象更新 。
var product = new Product()
{
ProductId = 1,
ProductCode = "1001",
ProductName = "测试商品1"
};
//注意:标记KeyAuttribute特性属性或使用Where条件,为了安全起见全表更新将必须使用Where方法
var result = db.Update(product).Exceute();
Console.WriteLine($"对象更新 受影响行数 {result}");
指定列更新 。
var result = db.Update<Product>(new Product() { ProductCode = "1001", ProductName = "1002" }).Columns(c=> new { c.ProductCode , c.ProductName }).Exceute();
// 推荐使用表达式 c=>new {} 好处更改属性名称可以同步修改
忽略列更新 。
var result = db.Update<Product>(new Product() { ProductCode = "1001", ProductName = "1002" }).IgnoreColumns(c=> new { c.Custom1 }).Exceute();
// 同上使用方法一样
实体对象列表更新 。
var list = new List<Product>();
for (int i = 0; i < 2022; i++)
{
list.Add(new Product()
{
ProductCode = $"编号{i + 1}",
ProductName = $"名称{i + 1}"
});
}
//注意:标记KeyAuttribute特性属性或使用WhereColumns方法指定更新条件列
var result = db.Update(list).Exceute();
Console.WriteLine($"对象列表更新 受影响行数 {result}");
匿名对象更新 。
var obj = new
{
ProductId = 1,
ProductCode = "1001",
ProductName = "测试商品1"
};
//注意:需要显示指定表名称 以及更新条件 使用 Where或者WhereColumns方法均可
var result = db.Update(obj).As("product").WhereColumns("ProductId").Exceute();
Console.WriteLine($"匿名对象更新 受影响行数 {result}");
匿名对象列表更新 。
var list = new List<object>();
for (int i = 0; i < 2022; i++)
{
list.Add(new
{
ProductId = i + 1,
ProductCode = $"编号{i + 1}",
ProductName = $"名称{i + 1}"
});
}
//由于是匿名对象需要显示指定表名称,使用WhereColumns方法指定更新条件列
var result = db.Update(list).As("Product").WhereColumns("ProductId").Exceute();
Console.WriteLine($"匿名对象列表更新 受影响行数 {result}");
字典更新 。
var product = new Dictionary<string, object>()
{
{ "ProductId",1},
{"ProductCode","1001"},
{ "ProductName","测试商品1"}
};
var result = db.Update(product).As("Product").WhereColumns("ProductId").Exceute();
Console.WriteLine($"字典更新 受影响行数 {result}");
字典列表更新 。
var list = new List<Dictionary<string, object>>();
for (int i = 0; i < 2022; i++)
{
list.Add(new Dictionary<string, object>()
{
{ "ProductId",i+1},
{"ProductCode",$"更新编号:{i+1}"},
{ "ProductName",$"更新商品:{i + 1}"}
});
}
var result = db.Update(list).As("Product").WhereColumns("ProductId").Exceute();
Console.WriteLine($"字典列表更新 受影响行数 {result}");
指定条件更新 。
var product = new Product()
{
ProductId = 1,
ProductCode = "1001",
ProductName = "测试商品1"
};
var result = db.Update(product).Where(p => p.ProductId == 100).Exceute();
Console.WriteLine($"表达式更新 受影响行数 {result}");
并发更新 乐观锁-版本控制 。
//注意:仅支持非列表更新 版本列数据类型仅支持 object、string、Guid 时间类型存在精度丢失所以不做支持
var obj = db.Query<Product>().Where(w => w.ProductId == 1).Frist();
obj.Custom1 = "测试版本控制修改";
//参数为 true 更新失败将抛出异常
var result = db.Update(obj).ExceuteWithOptLock(true);
单一查询 。
var data = db.Query<Product>().First();
列表查询 。
var data = db.Query<Product>().ToList();
返回单个字典 。
var data = db.Query<Product>().ToDictionary();
返回字典列表 。
var data = db.Query<Product>().ToDictionaryList();
分页查询 。
//分页查询不返回总数
var data = db.Query<Product>().ToPageList(1,100);
//分页查询返回总数
var total = 0;//定义总数变量
var data = db.Query<Product>().ToPageList(1, 1, ref total);
Console.WriteLine($"总数:{total}");
计数查询 。
var data = db.Query<Product>().Count();
任何查询 。
var data = db.Query<Product>().Any();
条件查询 。
var data = db.Query<Product>().Where(w => w.ProductId == 1).ToList;
Like 查询 。
var data = db.Query<Product>().Where(w => w.ProductName.StartsWith("左模糊") || w.ProductName.EndsWith("右模糊") || w.ProductName.Contains("全模糊")).ToList();
Not Like查询 。
var data = db.Query<Product>().Where(w => !w.ProductName.StartsWith("左模糊") || !w.ProductName.EndsWith("右模糊") || !w.ProductName.Contains("全模糊")).ToList();
Select查询 (选择字段) 。
var data = db.Query<Product>().Select(s => new
{
s.ProductId,
s.ProductName
}).ToList();
Select查询 (Case When) 。
var data = db.Query<Product>().Select(s => new
{
CaseTest1 = SqlFunc.Case(s.Custom1).When("1").Then("xx1").When("2").Then("xx2").Else("xx3").End(),
CaseTest2 = SqlFunc.CaseWhen<string>(s.Custom1 == "1").Then("xx1").When(s.Custom1 == "2").Then("xx2").Else("xx3").End()
}).ToList();
分组查询 。
var data = db.Query<Product>().GroupBy(s => new
{
s.ProductId,
s.ProductName
}).ToList();
分组聚合查询 。
var sql = db.Query<Order>().InnerJoin<OrderDetail>((a, b) => a.OrderId == b.OrderId).GroupBy((a, b) => new
{
a.OrderCode
}).Select((a, b) => new
{
a.OrderCode,
Sum_Qty = SqlFunc.Sum(b.Qty)//支持嵌套
}).ToList();
排序查询 。
var data = db.Query<Product>().OrderBy(s => new
{
s.CreateTime
}).ToList();
//这是多个字段排序使用方法 还有其它重载方法
Having查询 。
var data = db.Query<Product>().GroupBy(s => new
{
s.ProductId,
s.ProductName
}).Having(s => SqlFunc.Count(s.ProductId) > 1).ToList();
//必须先使用GroupBy方法 懂得都懂
联表查询 。
var data = db.Query<Product>().LeftJoin<Class1>((a, b) => a.ProductId == b.ProductId).ToList();
// 右连接 RightJoin 内连接 InnerJoin 全连接 FullJoin
联合查询 。
var query1 = db.Query<Product>();
var query2 = db.Query<Product>();
db.Union(query1, query2);//联合
db.UnionAll(query1, query2);//全联合
//执行查询调用Toxx方法
导航查询 (支持无限层级) 。
/// <summary>
/// 类别
/// </summary>
public class Category
{
/// <summary>
/// 类别ID
/// </summary>
[Key]
public int CategoryId { get; set; }
/// <summary>
/// 类别名称
/// </summary>
public string CategoryName { get; set; }
/// <summary>
/// 产品 Navigate MainName和ChildName 可不显示指定,会自动查找主键匹配或ID为结尾的属性
/// </summary>
[Navigate(MainName = nameof(CategoryId), ChildName = nameof(Product.CategoryId))]
public IEnumerable<Product> Products { get; set; }
}
var data = db.Query<Category>()
.Include(i => i.Products)
.ThenInclude(i => i.Category)
.ToList();
查询并插入 仅支持同实例的数据库 跨库 个人还是建议 用事务分开写查询和插入 。
//方式1
var result1 = db.Query<Product>().Where(w => w.ProductId == 1489087).Select(s => new
{
s.ProductCode,
s.ProductName
}).Insert<Product>(p => new
{
p.ProductCode,
p.ProductName
});
//方式2
var result2 = db.Query<Product>().Where(w => w.ProductId == 1489087).Select(s => new
{
s.ProductCode,
s.ProductName
}).Insert("表名称 同实例不同库 可以使用 db.数据库名称.表名称 ", "列名称1", "列名称2");
//方式3 需要注意同方式2 一样
var result3 = db.Query<Product>().Where(w => w.ProductId == 1489087).Select(s => new
{
s.ProductCode,
s.ProductName
}).Insert("表名称 同实例不同库 可以使用 db.数据库名称.表名称 ", new List<string>() { "列名称1" });
In查询 。
var data1 = db.Query<Product>().Where(w => new List<string>(){"1001", "1002"}.Contains(w.ProductCode)).ToList();
Select嵌套查询和子查询 。
var data1 = db.Query<Product>().Select(s => new
{
XX = db.Query<Product>().Select(s => 1).First()//需调用返回结果的方法 否则无法解析
}).First();
//进价用法,下面示例方法的重载均支持
var query = db.Query<Product>().Select(s => new
{
WithAttr_First = db.QueryWithAttr<Product>().First(),
WithAttr_FirstAsync = db.QueryWithAttr<Product>().FirstAsync(),
WithAttr_ToList = db.QueryWithAttr<Product>().ToList(),
WithAttr_ToListAsync = db.QueryWithAttr<Product>().ToListAsync(),
First_1 = db.Query<Category>().Select(s => 1).First(),//解析成Sql
First = db.Query<Category>().First(),
FirstAsync = db.Query<Category>().FirstAsync(),
ToArray = db.Query<Category>().ToArray(),
ToArrayAsync = db.Query<Category>().ToArrayAsync(),
ToList = db.Query<Category>().ToList(),
ToListAsync = db.Query<Category>().ToListAsync(),
ToPageList = db.Query<Category>().ToPageList(1, 10),
ToPageListAsync = db.Query<Category>().ToPageListAsync(1, 10),
ToPageList_Count = db.Query<Category>().ToPageList(1, 10, ref count),
ToPageListAsync_Count = db.Query<Category>().ToPageListAsync(1, 10, refAsync),
ToDictionary = db.Query<Category>().ToDictionary(),
ToDictionaryAsync = db.Query<Category>().ToDictionaryAsync(),
ToDictionaryList = db.Query<Category>().ToDictionaryList(),
ToDictionaryListAsync = db.Query<Category>().ToDictionaryListAsync(),
ToDictionaryPageList = db.Query<Category>().ToDictionaryPageList(1, 10),
ToDictionaryPageListAsync = db.Query<Category>().ToDictionaryPageListAsync(1, 10),
ToDictionaryPageList_Count = db.Query<Category>().ToDictionaryPageList(1, 10, ref count),
ToDictionaryPageListAsync_Count = db.Query<Category>().ToDictionaryPageListAsync(1, 10, refAsync),
ToDataTable = db.Query<Category>().ToDataTable(),
ToDataTableAsync = db.Query<Category>().ToDataTableAsync(),
ObjToJson = db.Query<Category>().ObjToJson(),
ObjToJsonAsync = db.Query<Category>().ObjToJsonAsync(),
ObjListToJson = db.Query<Category>().ObjListToJson(),
ObjListToJsonAsync = db.Query<Category>().ObjListToJsonAsync(),
Max = db.Query<Category>().Max(a => a.CategoryId),//解析成Sql
MaxAsync = db.Query<Category>().MaxAsync(a => a.CategoryId),
Min = db.Query<Category>().Min(a => a.CategoryId),//解析成Sql
MinAsync = db.Query<Category>().MinAsync(a => a.CategoryId),
Count = db.Query<Category>().Count(),//解析成Sql
CountAsync = db.Query<Category>().CountAsync(),
Sum = db.Query<Category>().Sum(s => s.CategoryId),//解析成Sql
SumAsync = db.Query<Category>().SumAsync(s => s.CategoryId),
Avg = db.Query<Category>().Avg(s => s.CategoryId),//解析成Sql
AvgAsync = db.Query<Category>().AvgAsync(s => s.CategoryId)
});
var data2= query.First();
From子查询 。
var subQuery = db.Query<Product>();
var data = db.Query(subQuery).OrderBy(o => o.ProductCode).ToList();
Join子查询 。
var subQuery = db.Query<Product>();
var data = db.Query<Product>().InnerJoin(subQuery, (a, b) => a.ProductId == b.ProductId).ToList();
Include查询 。
// 联表条件 默认优先匹配主键 其次带有ID结尾的名称
var data = db.Query<Category>().Include(i => i.Products).ToList();
Exists查询 。
var data = db.Query<Product>()
.Where(w => db.Query<Product>().WhereIF(!string.IsNullOrWhiteSpace("测试"), a => a.ProductId == 1).Select(s => 1).Any())
.Select(s => new
{
s.ProductId,
s.ProductCode
}).ToList();
查询绑定字段(注意 字段必须是公开的,否则绑定外部无法访问,没有意义) 。
//当某些字段需要参与计算并且不返回前端时推荐用字段绑定,无需从A实体转换到B实体,强烈推荐此方式
var data = db.Query<Product>().Select(s => new Product()
{
_xx = s.ProductName
}).First();
动态表达式 命名空间 Fast.Framework.Utils 。
var ex = DynamicWhereExp.Create<Product>().AndIF(1 == 1, a => a.DeleteMark == true).Build();
var data = db.Query<Product>().Where(ex).ToList();
Sql函数 自定义函数 需引入命名空间 Fast.Framework.Utils 使用SqlFunc类 。
SqlServer 。
类型转换 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
ToString | CONVERT( VARCHAR(255),123) | 转换 VARCHAR | 否 |
ToDateTime | CONVERT( DATETIME,‘2022-09-16’) | 转换 DATETIME | 否 |
ToDecimal | CONVERT( DECIMAL(10,6),‘123’) | 转换 DECIMAL | 否 |
ToDouble | CONVERT( NUMERIC(10,6),‘123’) | 转换 NUMERIC | 否 |
ToSingle | CONVERT( FLOAT,‘123’) | 转换 FLOAT | 否 |
ToInt32 | CONVERT( INT,‘123’) | 转换 INT | 否 |
ToInt64 | CONVERT( BIGINT,‘123’) | 转换 BIGINT | 否 |
ToBoolean | CONVERT( BIT,‘1’) | 转换 BIT | 否 |
ToChar | CONVERT( CHAR(2),'x') | 转换 CHAR | 否 |
聚合函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
Max | MAX( a.[xx] ) | 最大值 | 是 |
Min | MIN( a.[xx] ) | 最小值 | 是 |
Count | COUNT( a.[xx] ) | 计数 | 是 |
Sum | SUM( a.[xx] ) | 合计 | 是 |
Avg | AVG( a.[xx] ) | 平均 | 是 |
数学函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
Abs | ABS( a.[xx] ) | 绝对值 | 是 |
Round | ROUND( a.[xx] ,2 ) | 四舍五入 | 是 |
字符串函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
StartsWith | LIKE 'xx'+‘%’ | 左模糊 | 否 |
EndsWith | LIKE ‘%’+'xx' | 右模糊 | 否 |
Contains | LIKE ‘%’+'xx'+‘%’ | 全模糊 | 否 |
SubString | SUBSTRING( 'xxxxxx' ,1,3) | 截取 | 否 |
Replace | REPLACE( 'xxx','x','y') | 替换 | 否 |
Len | LEN( 'xxx' ) | 长度 | 是 |
TrimStart | LTRIM( ' xx ' ) | 修剪起始空格 | 否 |
TrimEnd | RTRIM( ' xx ' ) | 修剪末尾空格 | 否 |
ToUpper | UPPER( 'xx' ) | 大写 | 否 |
ToLower | LOWER( 'xx' ) | 小写 | 否 |
Concat | CONCAT(a.[xx1],a.[xx2]) | 字符串拼接 | 否 |
Operation | [CreateTime] >= @Now_1 | 日期、数值、字符串范围比较 | 是 |
日期函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
DateDiff | DATEDIFF( DAY ,a.[xx],b.[xx]) | 日期相差 | 是 |
AddYears | DATEADD( YEAR,a.[xx],1 ) | 添加年份 | 否 |
AddMonths | DATEADD( MONTH,a.[xx],1 ) | 添加月份 | 否 |
AddDays | DATEADD( DAY,a.[xx],1 ) | 添加天数 | 否 |
AddHours | DATEADD( HOUR,a.[xx],1 ) | 添加时 | 否 |
AddMinutes | DATEADD( MINUTE,a.[xx],1 ) | 添加分 | 否 |
AddSeconds | DATEADD( SECOND,a.[xx],1 ) | 添加秒 | 否 |
AddMilliseconds | DATEADD( MILLISECOND,a.[xx],1 ) | 添加毫秒 | 否 |
Year | YEAR( a.[xx] ) | 获取年份 | 是 |
Month | MONTH( a.[xx] ) | 获取月份 | 是 |
Day | DAY( a.[xx] ) | 获取天数 | 是 |
其它函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
NewGuid | NEWID() | 获取GUID | 否 |
Equals | p.[ProductCode] = '123' | 比较 | 否 |
IsNull | ISNULL(a.[xx],0) | 是否为空 | 是 |
Case | CASE | case | 是 |
When | WHEN | when | 是 |
Then | THEN | then | 是 |
Else | ELSE | else | 是 |
End | END | end | 是 |
MySql 。
类型转换 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
ToString | CAST( a.`xx` AS CHAR(510) ) | 转换 CHAR(510) | 否 |
ToDateTime | CAST( a.`xx` AS DATETIME ) | 转换 DATETIME | 否 |
ToDecimal | CAST( a.`xx` AS DECIMAL(10,6) ) | 转换 DECIMAL(10,6) | 否 |
ToDouble | CAST( a.`xx` AS DECIMAL(10,6) ) | 转换 DECIMAL(10,6) | 否 |
ToInt32 | CAST( a.`xx` AS DECIMAL(10) ) | 转换 DECIMAL(10) | 否 |
ToInt64 | CAST( a.`xx` AS DECIMAL(19) ) | 转换 DECIMAL(19) | 否 |
ToBoolean | CAST( a.`xx` AS UNSIGNED ) | 转换 UNSIGNED | 否 |
ToChar | CAST( a.`xx` AS CHAR(2) ) | 转换 CHAR(2) | 否 |
聚合函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
Max | MAX( a.`xx` ) | 最大值 | 是 |
Min | MIN( a.`xx` ) | 最小值 | 是 |
Count | COUNT( a.`xx` ) | 计数 | 是 |
Sum | SUM( a.`xx` ) | 合计 | 是 |
Avg | AVG( a.`xx` ) | 平均 | 是 |
数学函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
Abs | ABS( a.`xx` ) | 绝对值 | 是 |
Round | ROUND( a.`xx` ,2 ) | 四舍五入 | 是 |
字符串函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
StartsWith | LIKE CONCAT( 'xx','%' ) | 左模糊 | 否 |
EndsWith | LIKE CONCAT( '%','xx' ) | 右模糊 | 否 |
Contains | LIKE CONCAT( '%','xx','%' ) | 全模糊 | 否 |
SubString | SUBSTRING( 'xxxxxx' ,1,3 ) | 截取 | 否 |
Replace | REPLACE( 'xxx','x','y' ) | 替换 | 否 |
Len | LEN( 'xxx' ) | 长度 | 是 |
Trim | TRIM( ' xx ' ) | 修剪空格 | 否 |
TrimStart | LTRIM( ' xx ' ) | 修剪起始空格 | 否 |
TrimEnd | RTRIM( ' xx ' ) | 修剪末尾空格 | 否 |
ToUpper | UPPER( 'xx' ) | 大写 | 否 |
ToLower | LOWER( 'xx' ) | 小写 | 否 |
Concat | CONCAT(a.`xx1`,a.`xx2`) | 字符串拼接 | 否 |
Operation | `CreateTime` >= @Now_1 | 日期、数值、字符串范围比较 | 是 |
日期函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
DateDiff | DATEDIFF( a.`xx`,b.`xx` ) | 日期相差 返回相差天数 | 是 |
TimestampDiff | TIMESTAMPDIFF( DAY,a.`xx`,b.`xx` ) | 日期相差 指定时间单位 | 是 |
AddYears | DATE_ADD( a.`xx`,INTERVAL 1 YEAR ) | 添加年份 | 否 |
AddMonths | DATE_ADD( a.`xx`,INTERVAL 1 MONTH ) | 添加月份 | 否 |
AddDays | DATE_ADD( a.`xx`,INTERVAL 1 DAY ) | 添加天数 | 否 |
AddHours | DATE_ADD( a.`xx`,INTERVAL 1 HOUR ) | 添加时 | 否 |
AddMinutes | DATE_ADD( a.`xx`,INTERVAL 1 MINUTE ) | 添加分 | 否 |
AddSeconds | DATE_ADD( a.`xx`,INTERVAL 1 SECOND ) | 添加秒 | 否 |
AddMilliseconds | DATE_ADD( a.`xx`,INTERVAL 1 MINUTE_SECOND ) | 添加毫秒 | 否 |
Year | YEAR( a.`xx` ) | 获取年份 | 是 |
Month | MONTH( a.`xx` ) | 获取月份 | 是 |
Day | DAY( a.`xx` ) | 获取天数 | 是 |
其它函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
NewGuid | UUID() | 获取GUID | 否 |
Equals | p.`ProductCode` = '123' | 比较 | 否 |
IfNull | IFNULL( a.`xx`,0 ) | 如果为空 | 是 |
Case | CASE | case | 是 |
When | WHEN | when | 是 |
Then | THEN | then | 是 |
Else | ELSE | else | 是 |
End | END | end | 是 |
Oracle 。
类型转换 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
ToString | CAST( a."xx" AS VARCHAR(255) ) | 转换 VARCHAR | 否 |
ToDateTime | TO_TIMESTAMP( a."xx" ,'yyyy-MM-dd hh:mi:ss.ff') | 转换 DATETIME | 否 |
ToDecimal | CAST( a."xx" AS DECIMAL(10,6) ) | 转换 DECIMAL | 否 |
ToDouble | CAST( a."xx" AS NUMBER ) | 转换 NUMBER | 否 |
ToSingle | CAST( a."xx" AS FLOAT ) | 转换 FLOAT | 否 |
ToInt32 | CAST( a."xx" AS INT ) | 转换 INT | 否 |
ToInt64 | CAST( a."xx" AS NUMBER ) | 转换 NUMBER | 否 |
ToBoolean | CAST( a."xx" AS CHAR(1) ) | 转换 CHAR | 否 |
ToChar | CAST( a."xx" AS CHAR(2) ) | 转换 CHAR | 否 |
聚合函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
Max | MAX( a."xx" ) | 最大值 | 是 |
Min | MIN( a."xx" ) | 最小值 | 是 |
Count | COUNT( a."xx" ) | 计数 | 是 |
Sum | SUM( a."xx" ) | 合计 | 是 |
Avg | AVG( a."xx" ) | 平均 | 是 |
数学函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
Abs | ABS( a."xx" ) | 绝对值 | 是 |
Round | ROUND( a."xx" ,2 ) | 四舍五入 | 是 |
字符串函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
StartsWith | LIKE CONCAT( 'xx','%' ) | 左模糊 | 否 |
EndsWith | LIKE CONCAT( '%','xx' ) | 右模糊 | 否 |
Contains | LIKE CONCAT( '%','xx','%' ) | 全模糊 | 否 |
SubString | SUBSTRING( 'xxxxxx' ,1,3) | 截取 | 否 |
Replace | REPLACE( 'xxx','x','y') | 替换 | 否 |
Length | LENGTH( 'xxx' ) | 长度 | 是 |
TrimStart | LTRIM( ' xx ' ) | 修剪起始空格 | 否 |
TrimEnd | RTRIM( ' xx ' ) | 修剪末尾空格 | 否 |
ToUpper | UPPER( 'xx' ) | 大写 | 否 |
ToLower | LOWER( 'xx' ) | 小写 | 否 |
Concat | CONCAT(a."xx1",a."xx2") | 字符串拼接 | 否 |
Operation | ”CreateTime“ >= @Now_1 | 日期、数值、字符串范围比较 | 是 |
日期函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
Year | EXTRACT( YEAR FROM a."xx" ) | 获取年份 | 是 |
Month | EXTRACT( MONTH FROM a."xx" ) | 获取月份 | 是 |
Day | EXTRACT( DAY FROM a."xx" ) | 获取天数 | 是 |
其它函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
Equals | p."ProductCode" = '123' | 比较 | 否 |
Nvl | NVL( a."xx",0 ) | 空,默认 | 是 |
Case | CASE | case | 是 |
When | WHEN | when | 是 |
Then | THEN | then | 是 |
Else | ELSE | else | 是 |
End | END | end | 是 |
PostgreSql 。
类型转换 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
ToString | a."xx"::VARCHAR(255) | 转换 VARCHAR | 否 |
ToDateTime | a."xx"::TIMESTAMP | 转换 TIMESTAMP | 否 |
ToDecimal | a."xx"::DECIMAL(10,6) | 转换 DECIMAL | 否 |
ToDouble | a."xx"::NUMERIC(10,6) | 转换 NUMERIC | 否 |
ToSingle | a."xx"::REAL | 转换 REAL | 否 |
ToInt32 | a."xx"::INTEGER | 转换 INT | 否 |
ToInt64 | a."xx"::BIGINT | 转换 BIGINT | 否 |
ToBoolean | a."xx"::BOOLEAN | 转换 BOOLEAN | 否 |
ToChar | a."xx"::CHAR(2) | 转换 CHAR | 否 |
聚合函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
Max | MAX( a."xx" ) | 最大值 | 是 |
Min | MIN( a."xx" ) | 最小值 | 是 |
Count | COUNT( a."xx" ) | 计数 | 是 |
Sum | SUM( a."xx" ) | 合计 | 是 |
Avg | AVG( a."xx" ) | 平均 | 是 |
数学函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
Abs | ABS( a."xx" ) | 绝对值 | 是 |
Round | ROUND( a."xx" ,2 ) | 四舍五入 | 是 |
字符串函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
StartsWith | LIKE CONCAT( '%','xx' ) | 左模糊 | 否 |
EndsWith | LIKE CONCAT( 'xx','%' ) | 右模糊 | 否 |
Contains | LIKE CONCAT( '%','xx','%' ) | 全模糊 | 否 |
SubString | SUBSTRING( 'xxxxxx' ,1,3 ) | 截取 | 否 |
Replace | REPLACE( 'xxx','x','y' ) | 替换 | 否 |
Length | LENGTH( 'xxx' ) | 长度 | 是 |
Trim | TRIM( ' xx ' ) | 修剪空格 | 否 |
TrimStart | LTRIM( ' xx ' ) | 修剪起始空格 | 否 |
TrimEnd | RTRIM( ' xx ' ) | 修剪末尾空格 | 否 |
ToUpper | UPPER( 'xx' ) | 大写 | 否 |
ToLower | LOWER( 'xx' ) | 小写 | 否 |
Concat | CONCAT(a."xx1",a."xx2") | 字符串拼接 | 否 |
Operation | ”CreateTime“ >= @Now_1 | 日期、数值、字符串范围比较 | 是 |
日期函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
AddYears | a."xx" + INTERVAL '1 YEAR' | 添加年份 | 否 |
AddMonths | a."xx" + INTERVAL '1 MONTH' | 添加月份 | 否 |
AddDays | a."xx" + INTERVAL '1 DAY' | 添加天数 | 否 |
AddHours | a."xx" + INTERVAL '1 HOUR' | 添加时 | 否 |
AddMinutes | a."xx" + INTERVAL '1 MINUTE' | 添加分 | 否 |
AddSeconds | a."xx" + INTERVAL '1 SECOND' | 添加秒 | 否 |
AddMilliseconds | a."xx" + INTERVAL '1 MINUTE_SECOND' | 添加毫秒 | 否 |
Year | YEAR( a."xx" ) | 获取年份 | 是 |
Month | MONTH( a."xx" ) | 获取月份 | 是 |
Day | DAY( a."xx" ) | 获取天数 | 是 |
查询函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
In | IN ( a."xx" ,'x1','x2','x3' ) | In查询 | 是 |
NotIn | NOT IN ( a."xx" ,'x1','x2','x3' ) | Not In查询 | 是 |
其它函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
Equals | p.”ProductCode“ = '123' | 比较 | 否 |
Case | CASE | case | 是 |
When | WHEN | when | 是 |
Then | THEN | then | 是 |
Else | ELSE | else | 是 |
End | END | end | 是 |
Sqlite 。
类型转换 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
ToString | CAST(a.[xx] AS TEXT ) | 转换 TEXT | 否 |
ToDateTime | DATETIME( a.[xx] ) | 转换 DateTime | 否 |
ToDecimal | CAST(a.[xx] AS DECIMAL(10,6) ) | 转换 DECIMAL | 否 |
ToDouble | CAST(a.[xx] AS NUMERIC(10,6) ) | 转换 NUMERIC | 否 |
ToSingle | CAST(a.[xx] AS FLOAT ) | 转换 FLOAT | 否 |
ToInt32 | CAST(a.[xx] AS INTEGER ) | 转换 INTEGER | 否 |
ToInt64 | CAST(a.[xx] AS BIGINT ) | 转换 BIGINT | 否 |
ToBoolean | CAST(a.[xx] AS CHAR(1) ) | 转换 CHAR | 否 |
ToChar | CAST(a.[xx] AS CHAR(2) ) | 转换 CHAR | 否 |
聚合函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
Max | MAX( a.[xx] ) | 最大值 | 是 |
Min | MIN( a.[xx] ) | 最小值 | 是 |
Count | COUNT( a.[xx] ) | 计数 | 是 |
Sum | SUM( a.[xx] ) | 合计 | 是 |
Avg | AVG( a.[xx] ) | 平均 | 是 |
数学函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
Abs | ABS( a.[xx] ) | 绝对值 | 是 |
Round | ROUND( a.[xx] ,2 ) | 四舍五入 | 是 |
字符串函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
StartsWith | LIKE 'xx'||'%' | 左模糊 | 否 |
EndsWith | LIKE '%'||'xx' | 否 | |
Contains | LIKE '%'||'xx'||'%' | 全模糊 | 否 |
SubString | SUBSTRING( 'xxxxxx' ,1,3 ) | 截取 | 否 |
Replace | REPLACE( 'xxx','x','y' ) | 替换 | 否 |
Length | LENGTH( 'xxx' ) | 长度 | 是 |
Trim | TRIM( ' xx ' ) | 修剪空格 | 否 |
TrimStart | LTRIM( ' xx ' ) | 修剪起始空格 | 否 |
TrimEnd | RTRIM( ' xx ' ) | 修剪末尾空格 | 否 |
ToUpper | UPPER( 'xx' ) | 大写 | 否 |
ToLower | LOWER( 'xx' ) | 小写 | 否 |
Operation | [CreateTime] >= @Now_1 | 日期、数值、字符串范围比较 | 是 |
日期函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
AddYears | DATETIME( a.[xx],'1 YEAR' ) | 添加年份 | 否 |
AddMonths | DATETIME( a.[xx],'1 MONTH' ) | 添加月份 | 否 |
AddDays | DATETIME( a.[xx],'1 DAY' ) | 添加天数 | 否 |
AddHours | DATETIME( a.[xx],'1 HOUR' ) | 添加时 | 否 |
AddMinutes | DATETIME( a.[xx],'1 MINUTE' ) | 添加分 | 否 |
AddSeconds | DATETIME( a.[xx],'1 SECOND' ) | 添加秒 | 否 |
AddMilliseconds | DATETIME( a.[xx],'1 YEAR' ) | 添加毫秒 | 否 |
Year | STRFTIME( '%Y', a.[xx] ) | 获取年份 | 是 |
Month | STRFTIME( '%m', a.[xx] ) | 获取月份 | 是 |
Day | STRFTIME( '%j', a.[xx] ) | 获取天数 | 是 |
其它函数 。
方法名称 | 解析示例值 | 说明 | 自定义函数 |
---|---|---|---|
Equals | p.”ProductCode“ = '123' | 比较 | 否 |
Case | CASE | case | 是 |
When | WHEN | when | 是 |
Then | THEN | then | 是 |
Else | ELSE | else | 是 |
End | END | end | 是 |
添加自定义函数解析 。
//注意:只能扩展未实现的方法名称 不能覆盖原有的实现
Models.DbType.MySQL.AddSqlFunc("方法名称", (visit, method, sqlStack) =>
{
//解析逻辑
});
db.Aop.DbLog = (sql, dp) =>
{
Console.WriteLine($"执行Sql:{sql}");
if (dp != null)
{
foreach (var item in dp)
{
Console.WriteLine($"参数名称:{item.ParameterName} 参数值:{item.ParameterValue}");
}
}
};
普通事务 。
try
{
db.Ado.BeginTran();//开启事务
// 执行 CRUD
db.Ado.CommitTran();//提交事务
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
db.Ado.RollbackTran();//回滚事务
}
更大范围的事务 。
try
{
db.BeginTran();//开启事务
// 执行 CRUD
db.CommitTran();//提交事务
}
catch (Exception ex)
{
db.RollbackTran();//回滚事务
Console.WriteLine(ex.Message);
}
改变数据库 。
//数据库配置可从Json配置文件加载
IDbContext db = new DbContext(new List<DbOptions>() {
new DbOptions()
{
DbId = "1",
DbType = Models.DbType.SQLServer,
ProviderName = "System.Data.SqlClient",
FactoryName = "System.Data.SqlClient.SqlClientFactory,System.Data",
ConnectionStrings = "server=localhost;database=Test;user=sa;pwd=123456789;min pool size=0;max pool size=100;connect timeout=120;"
},
new DbOptions()
{
DbId = "2",
DbType = Models.DbType.MySQL,
ProviderName = "MySqlConnector",
FactoryName = "MySqlConnector.MySqlConnectorFactory,MySqlConnector",
ConnectionStrings = "server=localhost;database=Test;user=root;pwd=123456789;port=3306;min pool size=0;max pool size=100;connect timeout=120;"
}});
db.ChangeDb("2");//切换到MySQL
/// <summary>
/// 产品
/// </summary>
[Table("ProductMain")]
public class Product
{
/// <summary>
/// 产品ID
/// </summary>
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ProductId { get; set; }
/// <summary>
/// 产品编号
/// </summary>
[Column("ProductCode")]//不标记默认取当前属性名称
public string ProductCode { get; set; }
/// <summary>
/// 自定义1
/// </summary>
[NotMapped]
public string Custom1 { get; set; }
/// <summary>
/// 自定义2
/// </summary>
[Column(TypeName="Json")]//类型标记为Json格式对象 匿名对象属性以及字典值类型 IsClass&&!type.Equals(typeof(string)) 将自动序列化成Json格式
public Category Custom2 { get; set; }
}
// 原始起步
// var conn = db.Ado.DbProviderFactory.CreateConnection();
// var cmd = conn.CreateCommand();
// 封装的方法分别以Execute和Create开头以及预处理 PrepareCommand 方法
// 该方法可以自动帮你处理执行的预操作,主要作用是代码复用。
// 当有非常复杂的查询 ORM不能满足需求的时候可以使用原生Ado满足业务需求
// 构建数据集核心扩展方法 分别有 FristBuild ListBuild DictionaryBuild DictionaryListBuild
var data = db.Ado.ExecuteReader(CommandType.Text, "select * from product", null).ListBuild<Product>();
注册数据库上下文和工作单元服务 。
var builder = WebApplication.CreateBuilder(args);
var configuration = builder.Configuration;
// 添加数据库上下文服务
builder.Services.AddFastDbContext();
// 添加工作单元服务
builder.Services.AddUnitOfWork();
// 加载数据库配置
builder.Services.Configure<List<DbOptions>>(configuration.GetSection("DbConfig"));
实际应用 。
/// <summary>
/// 工作单元
/// </summary>
private readonly IUnitOfWork unitOfWork;
/// <summary>
/// 构造方法
/// </summary>
/// <param name="unitOfWork">工作单元</param>
public UnitOfWorkTestService(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
/// <summary>
/// 测试
/// </summary>
/// <returns></returns>
public string Test()
{
//unitOfWork 对象无需显示使用using
var result1 = unitOfWork.Db.Insert(new Category()
{
CategoryName = "类别3"
}).Exceute();
var result2 = unitOfWork.Db.Insert(new Product()
{
ProductCode = "测试工作单元",
}).Exceute();
unitOfWork.Commit();
return "工作单元执行完成...";
}
批复制 仅支持SqlServer Oracle MySql PostgreSql 。
var list = new List<Product>();
for (int j = 1; j <= 100000; j++)
{
list.Add(new Product()
{
CategoryId = 1,
ProductCode = $"测试编号_{Timestamp.CurrentTimestampSeconds()}_{j}",
ProductName = $"测试名称_{Timestamp.CurrentTimestampSeconds()}_{j}",
CreateTime = DateTime.Now,
Custom1 = $"测试自定义1_{Timestamp.CurrentTimestampSeconds()}_{j}",
Custom2 = $"测试自定义2_{Timestamp.CurrentTimestampSeconds()}_{j}",
Custom3 = $"测试自定义3_{Timestamp.CurrentTimestampSeconds()}_{j}",
Custom4 = $"测试自定义4_{Timestamp.CurrentTimestampSeconds()}_{j}",
Custom5 = $"测试自定义5_{Timestamp.CurrentTimestampSeconds()}_{j}",
Custom6 = $"测试自定义6_{Timestamp.CurrentTimestampSeconds()}_{j}",
Custom7 = $"测试自定义7_{Timestamp.CurrentTimestampSeconds()}_{j}",
Custom8 = $"测试自定义8_{Timestamp.CurrentTimestampSeconds()}_{j}",
Custom9 = $"测试自定义9_{Timestamp.CurrentTimestampSeconds()}_{j}",
Custom10 = $"测试自定义10_{Timestamp.CurrentTimestampSeconds()}_{j}",
Custom11 = $"测试自定义11_{Timestamp.CurrentTimestampSeconds()}_{j}",
Custom12 = $"测试自定义12_{Timestamp.CurrentTimestampSeconds()}_{j}",
});
}
db.Fast<Product>().BulkCopy(list);
最后此篇关于自研ORM(匠心之作)的文章就讲到这里了,如果你想了解更多关于自研ORM(匠心之作)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
请提及(大)ORM 和微 ORM 之间的区别。与大型 ORM 相比,微型 ORM 有何优势?例如。 Entity Framework ORM 和 dapper micro ORM 之间的区别。 最佳答
我有一个名为 User 的模型。我可以从 User 模型扩展另一个模型 Admin/mod 吗?我找到了续集文档,但我没有找到 最佳答案 是的,查看 Associations documentatio
你对数据访问层有什么建议?使用 Entity Framework 和 Hibernate OR 代码生成器(如 Subsonic、.netTiers、T4 等)等 ORM? 最佳答案 对我来说,这很简
我编写了一个代码生成器,它为给定的 SQL Server/CE 数据库生成 POCO 和存储库。没什么花哨的,只有使用经典 ADO.Net 的简单 CRUD 程序。我的问题是,为什么我应该使用像 L2
我扩展了Android.Application类,以便保持状态(将应用程序用作单例)。 但是,我现在想使用Sugar ORM库简化我的数据库访问,但是Sugar文档(http://satyan.git
我正在阅读 OOP 设计模式和框架设计,发现自己对术语 ORM 和持久性框架之间的区别有点不确定。 ORM 是 PF 的一种吗?您可以期待两者有哪些不同的功能? 最佳答案 我将 ORM 定义为将任何数
在 Jboss EAP 7.0 中加载 orm 文件时,我遇到了以下问题,但它在 Weblogic 中工作。 原因:org.hibernate.boot.MappingException:无法解析显式
我一直在研究 Massive ORM。不要忘记,只是看,我还没有做任何编码。 我对保存交易数据的可能性感兴趣。我已经看到可以在一个事务中在同一个表中保存 20 行。但是当我想在单个交易中保存一个订单并
好的。我刚刚开始在我的 Coldfusion 应用程序中使用 ORM。到现在为止一切都很顺利。我遇到了这个障碍。我有这两张表: 这是我用来将数据加载到页面中的代码。 if 的第二部分是默认加载,第一部
我有可以分配许多类别的帖子。所以它是一个多对多的关系。 我想计算每个类别中有多少帖子(符合特定标准),然后对结果进行排序。 我有: Select ( Select count(post.id)
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 8年前关闭。 Improve t
我正在评估如何使用后端的分布式键/值存储来实现某些东西。我希望在支持对象模型的键/值之上有一个层,该对象模型类似于我从对象关系映射器中获得的模型。 任何人都可以指出其他人这样做的任何例子吗?我主要是在
我正在使用 kohana ORM 以便从数据库中获取一些结果。我的问题是:即使我查阅了文档,我也找不到只选择我感兴趣的列的方法。更明确地说,我有: $sale_stock = Model::facto
在 ORM 之前,如果我想显示规范化表的组合输出,我只需执行快速 CFQUERY,将表连接到我想要的字段并显示输出。我只是无法使用 ORM 来解决它。 例如这两个表: customers (id,
异步 ORM 的真正含义是什么?它与常规 ORM 的行为有何不同? 它可以用在什么地方? 最佳答案 这意味着对它的调用会立即返回(不会阻塞)。您会在稍后的某个时间点获得结果,很可能是由于回调触发。
虽然代码优先非常适合部署和开发,但我看不出如何在投入生产后以代码优先的方式插入对域模型所做的更改。 我如何处理我们在生产过程中积累的数据? 我是否应该手动将数据从 A 版架构迁移到 B 版架构?我是否
像学说(事件记录)和Xyster(数据映射器),有什么区别? 最佳答案 不同之处在于域对象与数据访问层的分离程度。使用 ActiveRecord,它是一个对象,这使它变得非常简单。特别是如果您的类一对
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我在 ColdFusion 中有一个持久实体,我需要更新一个属性 property name="createdDateTime" ormtype="date"; 到 property name="cr
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我是一名优秀的程序员,十分优秀!