1.查看其它接口发现少了一个最重要的SaveBuilder。此文件是存放sql模板,where条件,select解析,组装成tosqlstring的最后一个类。

添加文件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Text.RegularExpressions; namespace SqlSugar
{
public class SaveBuilder : IDMLBuilder
{
public SaveBuilder()
{
this.sql = new StringBuilder();
this.DbColumnInfoList = new List<DbColumnInfo>();
this.SetValues = new List<KeyValuePair<string, string>>();
this.WhereValues = new List<string>();
this.Parameters = new List<SugarParameter>();
}
public SqlSugarProvider Context { get; set; }
public ILambdaExpressions LambdaExpressions { get; set; }
public ISqlBuilder Builder { get; set; }
public StringBuilder sql { get; set; }
public List<SugarParameter> Parameters { get; set; }
public string TableName { get; set; }
public string TableWithString { get; set; }
public List<DbColumnInfo> DbColumnInfoList { get; set; }
public List<string> WhereValues { get; set; }
public List<KeyValuePair<string, string>> SetValues { get; set; }
public bool IsNoUpdateNull { get; set; }
public bool IsNoUpdateDefaultValue { get; set; }
public List<string> PrimaryKeys { get; set; }
public bool IsOffIdentity { get; set; }
public bool IsWhereColumns { get; set; } /// <summary>
/// select x as X as a join T t on a.id = t.id
/// </summary> public virtual string SqlTemplate
{
get
{
return @"UPDATE {0} SET
{1} {2}"; }
} public virtual string SqlTemplateBatch
{
get
{
return @" SELECT {3} FROM (
{0} ) T ,{1} S WHERE {2}
; ";
}
} public virtual string SqlTemplateBatchSelect
{
get
{
return "{0} AS {1}";
}
} public virtual string SqlTemplateBatchUnion
{
get
{
return "\t\t\r\nUNION ALL ";
}
} public virtual void Clear()
{ }
public virtual string GetTableNameString
{
get
{
var result = Builder.GetTranslationTableName(TableName);
result += UtilConstants.Space;
if (this.TableWithString.HasValue())
{
result += TableWithString + UtilConstants.Space;
}
return result;
}
}
public virtual string GetTableNameStringNoWith
{
get
{
var result = Builder.GetTranslationTableName(TableName);
return result;
}
} public virtual ExpressionResult GetExpressionValue(Expression expression, ResolveExpressType resolveType, bool isMapping = true)
{
ILambdaExpressions resolveExpress = this.LambdaExpressions;
this.LambdaExpressions.Clear();
if (this.Context.CurrentConnectionConfig.MoreSettings != null)
{
resolveExpress.PgSqlIsAutoToLower = this.Context.CurrentConnectionConfig.MoreSettings.PgSqlIsAutoToLower;
}
else
{
resolveExpress.PgSqlIsAutoToLower = true;
}
if (isMapping)
{
resolveExpress.MappingColumns = Context.MappingColumns;
resolveExpress.MappingTables = Context.MappingTables;
resolveExpress.IgnoreComumnList = Context.IgnoreColumns;
resolveExpress.SqlFuncServices = Context.CurrentConnectionConfig.ConfigureExternalServices == null ? null : Context.CurrentConnectionConfig.ConfigureExternalServices.SqlFuncServices;
}
resolveExpress.InitMappingInfo = Context.InitMappingInfo;
resolveExpress.RefreshMapping = () =>
{
resolveExpress.MappingColumns = Context.MappingColumns;
resolveExpress.MappingTables = Context.MappingTables;
resolveExpress.IgnoreComumnList = Context.IgnoreColumns;
resolveExpress.SqlFuncServices = Context.CurrentConnectionConfig.ConfigureExternalServices == null ? null : Context.CurrentConnectionConfig.ConfigureExternalServices.SqlFuncServices;
};
resolveExpress.Resolve(expression, resolveType);
this.Parameters.AddRange(resolveExpress.Parameters);
var result = resolveExpress.Result;
return result;
}
public virtual string ToSqlString()
{
if (IsNoUpdateNull)
{
DbColumnInfoList = DbColumnInfoList.Where(it => it.Value != null).ToList();
}
if (IsNoUpdateDefaultValue)
{
DbColumnInfoList = DbColumnInfoList.Where(it => it.Value.ObjToString() !=UtilMethods.DefaultForType(it.PropertyType).ObjToString()).ToList();
}
var groupList = DbColumnInfoList.GroupBy(it => it.TableId).ToList(); return TomultipleSqlString(groupList);
} protected virtual string TomultipleSqlString(List<IGrouping<int, DbColumnInfo>> groupList)
{
Check.Exception(PrimaryKeys == null || PrimaryKeys.Count == 0, " Update List<T> need Primary key"); StringBuilder batchUpdateSql = new StringBuilder(); StringBuilder updateTable = new StringBuilder(); string selectString = string.Join(",", groupList.First().Select(
it =>
{
var result = "S." + it.DbColumnName + " " + Builder.GetTranslationColumnName(it.DbColumnName);
return result;
}
)); int i = 0;
foreach (var columns in groupList)
{
var isFirst = i == 0;
if (!isFirst)
{
updateTable.Append(SqlTemplateBatchUnion);
}
updateTable.Append("\r\n SELECT " + string.Join(",", columns.Where(o=>this.PrimaryKeys.Contains(o.DbColumnName)).Select(it => string.Format(SqlTemplateBatchSelect, FormatValue(it.Value), Builder.GetTranslationColumnName(it.DbColumnName)))));
++i;
}
updateTable.Append("\r\n");
string whereString = null;
//if (this.WhereValues.HasValue())
//{
// foreach (var item in WhereValues)
// {
// var isFirst = whereString == null;
// whereString += (isFirst ? null : " AND ");
// whereString += Regex.Replace(item, "\\" + this.Builder.SqlTranslationLeft, "S." + this.Builder.SqlTranslationLeft);
// }
//}
if (PrimaryKeys.HasValue())
{
foreach (var item in PrimaryKeys)
{
var isFirst = whereString == null;
whereString += (isFirst ? null : " AND ");
whereString += string.Format("S.{0}=T.{0}", Builder.GetTranslationColumnName(item));
}
}
batchUpdateSql.AppendFormat(SqlTemplateBatch, updateTable,this.TableName , whereString, selectString); return batchUpdateSql.ToString();
} public virtual object FormatValue(object value)
{
if (value == null)
{
return "NULL";
}
else
{
var type = UtilMethods.GetUnderType(value.GetType());
if (type == UtilConstants.DateType)
{
var date = value.ObjToDate();
if (date < Convert.ToDateTime("1900-1-1"))
{
date = Convert.ToDateTime("1900-1-1");
}
return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff") + "'";
}
else if (type == UtilConstants.ByteArrayType)
{
string bytesString = "0x" + BitConverter.ToString((byte[])value).Replace("-", "");
return bytesString;
}
else if (type.IsEnum())
{
return Convert.ToInt64(value);
}
else if (type == UtilConstants.BoolType)
{
return value.ObjToBool() ? "1" : "0";
}
else if (type == UtilConstants.StringType || type == UtilConstants.ObjType)
{
return "N'" + value.ToString().ToSqlFilter() + "'";
}
else
{
return "N'" + value.ToString() + "'";
}
}
}
}
}

2.修改SaveableProvider<T>使单主键查询数据库改为按条件解析查询existsObjects = this.Context.Ado.SqlQuery<T>(SaveBuilder.ToSqlString()).ToList();

3.添加动态表达式来筛选更新的数据以及插入的数据。

 public List<T> insertObjects
{
get
{
var isDisableMasterSlaveSeparation = this.Context.Ado.IsDisableMasterSlaveSeparation;
this.Context.Ado.IsDisableMasterSlaveSeparation = true;
List<T> result = new List<T>();
var pks = GetPrimaryKeys();
Check.Exception(pks.IsNullOrEmpty(), "Need primary key"); var pkInfo = this.EntityInfo.Columns.Where(it => it.IsIgnore == false)
.Where(it => pks.Contains(it.DbColumnName)).ToList();
if (existsObjects == null)
{
SaveBuilder.PrimaryKeys = pks;
existsObjects = this.Context.Ado.SqlQuery<T>(SaveBuilder.ToSqlString()).ToList();
}
this.Context.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation;
ParameterExpression param1 = Expression.Parameter(typeof(T), "it");
ParameterExpression param = Expression.Parameter(typeof(T), "e");
BinaryExpression mainBinaryExpression = null;
foreach (var info in pkInfo)
{
MemberExpression body = Expression.PropertyOrField(param, info.PropertyName);
MemberExpression body1 = Expression.PropertyOrField(param1, info.PropertyName);
var exp = Expression.Equal(body, body1); if (mainBinaryExpression == null)
{
mainBinaryExpression = exp;
}
else
{
mainBinaryExpression = Expression.AndAlso(mainBinaryExpression, exp);
}
}
var lambda = Expression.Lambda<Func<T, Boolean>>(mainBinaryExpression, new[] { param });
Expression anyExpression = Expression.Call(
typeof(Enumerable), "Any",
new Type[] { typeof(T) },
Expression.Constant(existsObjects), lambda
);
var lambda1 = Expression.Lambda<Func<T, Boolean>>(Expression.Not(anyExpression), new[] { param1 });
return saveObjects.Where(lambda1.Compile()).ToList();
}
}
public List<T> updatObjects
{
get
{
var isDisableMasterSlaveSeparation = this.Context.Ado.IsDisableMasterSlaveSeparation;
this.Context.Ado.IsDisableMasterSlaveSeparation = true;
List<T> result = new List<T>();
var pks = GetPrimaryKeys();
Check.Exception(pks.IsNullOrEmpty(), "Need primary key"); var pkInfo = this.EntityInfo.Columns.Where(it => it.IsIgnore == false)
.Where(it => pks.Contains(it.DbColumnName)).ToList();
if (existsObjects == null)
{
SaveBuilder.PrimaryKeys = pks;
existsObjects = this.Context.Ado.SqlQuery<T>(SaveBuilder.ToSqlString()).ToList();
}
this.Context.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation;
ParameterExpression param1 = Expression.Parameter(typeof(T), "it");
ParameterExpression param = Expression.Parameter(typeof(T), "e");
BinaryExpression mainBinaryExpression = null;
foreach (var info in pkInfo)
{
MemberExpression body = Expression.PropertyOrField(param, info.PropertyName);
MemberExpression body1 = Expression.PropertyOrField(param1, info.PropertyName);
var exp = Expression.Equal(body, body1); if (mainBinaryExpression == null)
{
mainBinaryExpression = exp;
}
else
{
mainBinaryExpression = Expression.AndAlso(mainBinaryExpression, exp);
}
}
var lambda = Expression.Lambda<Func<T, Boolean>>(mainBinaryExpression, new[] { param });
Expression anyExpression = Expression.Call(
typeof(Enumerable), "Any",
new Type[] { typeof(T) },
Expression.Constant(existsObjects), lambda
);
var lambda1 = Expression.Lambda<Func<T, Boolean>>(anyExpression, new[] { param1 });
return saveObjects.Where(lambda1.Compile()).ToList();
}
}

4.添加tosql来打印生成的sql

ISaveable 添加tosql接口

List<KeyValuePair<string, List<SugarParameter>>> ToSql();

SaveableProvider实现接口

public List<KeyValuePair<string, List<SugarParameter>>> ToSql()
{
List<KeyValuePair<string, List<SugarParameter>>> sqllist = new List<KeyValuePair<string, List<SugarParameter>>>();
LoadInsertable();
LoadUpdateable();
if (insertable != null)
{
var insertsql = insertable.ToSql();
sqllist.Add(insertsql);
}
if (updateable != null)
{
var updatesql = updateable.ToSql();
sqllist.Add(updatesql);
} return sqllist;
}

Demo地址:https://gitee.com/xuanyun2018/sqlsugardemo.git

下一章节扩展分库分表功能。

sqlsugar入门(4)-修改源码支持多主键保存ISaveable的更多相关文章

  1. ok6410 u-boot-2012.04.01移植二修改源码支持单板

    继ok6410 u-boot-2012.04.01移植一后修改代码,对ok6410单板初始化,主要包括时钟.串口.NAND.DDR等初始化.这些工作在以前的裸板程序都写了,直接拿来用.我觉得先写裸板程 ...

  2. 修改Cosbench源码 支持s3的 http range request 测试场景

    在视频点播的业务应用场景中,用户使用了ffmpeg工具做视频实时转码用. 而ffmpeg使用range 请求.而Cosbench不支持这种测试场景,所以需要修改源码支持这种测试场景. HTTP 协议介 ...

  3. Windows7 64位环境6sv2.1大气传输模型修改源码添加国产高分卫星GF-1 GF-2光谱响应支持

    下面开始添加国产卫星光谱响应的支持: 以下主要参考文章“6S大气传输模型修改源码添加.自定义卫星光谱响应(以HJ-1B CCD为例)”网址:http://blog.csdn.net/sam92/art ...

  4. 修改json源码支持datetime序列化

    修改json源码支持datetime序列化 import json import datetime now = datetime.datetime.today() json.dumps(now) 抛出 ...

  5. Python paramiko 修改源码实现用户命令抓取

    paramiko 源码修改 paramiko主要用来实现ssh客户端.服务端链接,上一节我们说到了堡垒机,堡垒机内有一个需求是“用户行为审计”,在这里我们就可以通过修改paramiko内文件的源码来实 ...

  6. Android5.1.1 - APK签名校验分析和修改源码绕过签名校验

    Android5.1.1 - APK签名校验分析和修改源码绕过签名校验 作者:寻禹@阿里聚安全 APK签名校验分析 找到PackageParser类,该类在文件“frameworks/base/cor ...

  7. mvcAPI (入门 3)(源码)

    mvcAPI (入门 3)(源码) http://download.csdn.net/detail/chunfang740/9078579

  8. element-ui 修改源码实践 --tranfer

    1.element-ui 地址:https://github.com/ElemeFE/element 2.修改elelment-ui版本:2.2.2(请选择和项目相对应的版本) 3.修改内容:穿梭框组 ...

  9. zookeeper-如何修改源码-《每日五分钟搞定大数据》

    本篇文章仅仅是起一个抛砖迎玉的作用,举一个如何修改源码的例子.文章的灵感来自 ZOOKEEPER-2784. 提一个问题先 之前的文章讲过zxid的设计,我们先复习下: zxid有64位,分成两部分: ...

随机推荐

  1. 什么是垃圾搜集(GC)?为什么要有GC呢?

    GC的全称是Gabage Collection,翻译过来就是"垃圾收集"的意思.那么我们为什么用GC呢? 那么我们接下来就来聊一聊GC的创造背景.在C和C++那个年代的程序员界的长 ...

  2. 基础篇:详解锁原理,volatile+cas、synchronized的底层实现

    目录 1 锁的分类 2 synchronized底层原理 3 Object的wait和notify方法原理 4 jvm对synchronized的优化 5 CAS的底层原理 6 CAS同步操作的问题 ...

  3. Java 内功修炼 之 数据结构与算法(一)

    一.基本认识 1.数据结构与算法的关系? (1)数据结构(data structure): 数据结构指的是 数据与数据 之间的结构关系.比如:数组.队列.哈希.树 等结构. (2)算法: 算法指的是 ...

  4. 票房和口碑称霸国庆档,用 Python 爬取猫眼评论区看看电影《我和我的家乡》到底有多牛

    今年的国庆档电影市场的表现还是比较强势的,两名主力<我和我的家乡>和<姜子牙>起到了很好的带头作用. <姜子牙>首日破 2 亿,一举刷新由<哪吒之魔童降世&g ...

  5. Python数据结构与算法之图的广度优先与深度优先搜索算法示例

    本文实例讲述了Python数据结构与算法之图的广度优先与深度优先搜索算法.分享给大家供大家参考,具体如下: 根据维基百科的伪代码实现: 广度优先BFS: 使用队列,集合 标记初始结点已被发现,放入队列 ...

  6. matplotlib.pyplot.imshow如何显示灰度图

    转载:https://www.zhihu.com/question/24058898 作者:采石工链接:https://www.zhihu.com/question/24058898/answer/1 ...

  7. matlab中bitshift 将位移动指定位数

    来源:https://ww2.mathworks.cn/help/matlab/ref/bitshift.html?searchHighlight=bitshift&s_tid=doc_src ...

  8. P4279 [SHOI2008]小约翰的游戏(Anti_nim)

    Link 题面 题目描述 小约翰经常和他的哥哥玩一个非常有趣的游戏:桌子上有 \(n\) 堆石子,小约翰和他的哥哥轮流取石子,每个人取的时候,可以随意选择一堆石子, 在这堆石子中取走任意多的石子,但不 ...

  9. linux下各种骚操作

    (备注:不定时更新) 1. ctrl+l  清屏快捷键,相当于clear 2. !+命令开头部分   执行最近执行的此条命令   ### 如!vi  编辑上一次用vi打开的文件, 3. echo $$ ...

  10. Springboot+Redis(发布订阅模式)跨多服务器实战

    一:redis中发布订阅功能(http://www.redis.cn/commands.html#pubsub) PSUBSCRIBE pattern [pattern -]:订阅一个或者多个符合pa ...