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. Spring Environment对象获取属性

    String[] activeProfiles = env.getActiveProfiles();//获取当前是启用哪一个个配置文件 System.out.println(Arrays.toStri ...

  2. 关于VS编译报错,但是错误信息未提示问题解决方案

    可能代码中引用了别的类库中的函数,然后未编译被引用库导致编译报错,重新编译被引用库然后再编译当前库即可解决问题

  3. 探究"补阶乘大法的本质"——糖水不等式!

    废话不多说先来康一条例题: 证明: 下面给出题目的一种解法(我称之为"补阶乘大法"): 思考:为什么补上一个阶乘(准确说不是阶乘,是两个数阶乘的之商)项,放缩后再给去掉,就能达到我 ...

  4. 023 01 Android 零基础入门 01 Java基础语法 03 Java运算符 03 算术运算符之——自增自减运算符

    023 01 Android 零基础入门 01 Java基础语法 03 Java运算符 03 算术运算符之--自增自减运算符 本文知识点:Java算术运算符中的自增自减运算符 自增自减运算符 之前我们 ...

  5. 01 学习人工智能,不做笔记?做笔记不知道如何输入数学公式?“onenote+Mathematics Add-In”拯救你!onenote安装数学输入公式插件Microsoft Mathematics Add-In for Word and OneNote教程走一波

    一.Microsoft Mathematics Add-In 插件下载 Microsoft Mathematics Add-In for Word and OneNote插件下载链接: https:/ ...

  6. apline无法向gitlab上传git lfs问题

    1 背景 在k8s中基于alpine做底层系统的容器进行git lfs push操作时,发现报错无法上传成功 Fatal error: Server error: http://git.ops.xxx ...

  7. 成理信安协会反序列化01-利用fastcoll实现md5碰撞

    虽然是反序列化的题目,但主要考点在利用fastcoll实现md5碰撞. 直接上源码 <?php show_source(__FILE__); class CDUTSEC { public $va ...

  8. 介绍使用Cordova和Web Starter Kit开发Android

    介绍 如今,每个人都想制作移动应用程序,为什么不呢?世界上有更多的移动设备比任何其他用户设备.Android尤其流行,但是为什么不从一个众所周知的跨平台应用的基础开始呢?Android的开发显然比其他 ...

  9. 设计完美windbg断点

    说到现场调试,断点是最重要的.通常,在生产环境中解决一个非常复杂的问题需要在本地.非生产环境中调试我自己的一台测试机器.我通常会调试有问题的进程或代码,以便更好地了解它是如何工作的,以及在我进入时需要 ...

  10. 多测师讲解html _有序列表005_高级讲师肖sir

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>有 ...