这个是对 4.0 Tuple 的升级吗?用起来应该更直观更方便
虽然对你不太熟悉,不过感觉你手头资源应该也挺丰富的。
不要担心,从今天起,说出你的故事,分享你的资源~
希望大家能从中了解到两点:
1、写代码时对数据要进行校验
2、报错时尽可能把错误情况展现给用户或维护人员,利人利己。
可以连接全面预算数据库查看数据情况:
--收款(供应商)
select * from LTTC_RECIPIENT where stdname like '济南历下飞达塑胶制品厂'
--银行账户
select STDCODE,CREATETIME,KHH,STDNAME,* from MD_BANKACCOUNT where stdname like '37001618810050022762'
欢迎大家补充。
Vue.js 是目前非常流行的用于 Web 开发的 js 框架,和它同一级别的有 Google 的 AngularJS,并且是在美华人由雨溪开发,很帅的一个小伙子。 有了它 Web 开发会变得灰常轻松愉悦。
猛击此处查看我们刚完成的第一个基于 Vue 的项目:
鲁泰物流运输系统移动版(https://app.lttc.cn/tms/)
Vue.js 作者无码图,是不是很帅。
baby,靠你了
你怎么还没换个性感的头像。
baby,靠你了
听说你新买了 C# 书,边学边培训,大城市的同事们就靠你了。
因为 DataSource 的相关请求处理是在客户端做的,所以我们完全可以写个 GetDataSet(DsRequest request) 的重载然后将 DsRequest 请求转成 Hashtbale,然后调用原来的 GetDataSet(Hashtable ht) 方法,这对编程者来说都是不可见的,所以之前的 GetDataSet(ht) 可以用,新程序你可以用 GetDataSet(qq) 来简化代码。
/// <summary>
/// 获取指定数据集的DataTable
/// </summary>
public DsResponse GetDataSet(DsRequest request)
{
Hashtable ht = DsRequestToHt(request); //将DsRequest转为Hashtable
//创建返回对象
DsResponse result = new DsResponse();
//获取数据
if (DataSource.GetDataSet(ht)["IsSuccess"].Equals("0")) return result;
//成功
result.IsSuccess = true;
string dsName = request.DataSetName;
result.DataSet = DataSource.DataSets[dsName] as DataSet;
result.DataTable = (DataSource.DataSets[dsName] as DataSet).Tables[0];
if (result.DataTable.Rows.Count > 0 && result.DataTable.Rows[0][0] != DBNull.Value)
{
result.Value = result.DataTable.Rows[0][0];
}
return result;
}
/// <summary>
/// 请求类转Hashtable
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
private Hashtable DsRequestToHt(DsRequest request)
{
Hashtable ht = new Hashtable();
ht["DataSetName"] = request.DataSetName;
if (!string.IsNullOrWhiteSpace(request.TableNames))
{
if (request.TableNames.Contains(","))
{
ht["TableNames"] = request.TableNames.Split(',');
}
else
{
ht["TableNames"] = request.TableNames;
}
}
//关键字(在这里我们把关键字加上大括号)
if (request.Keys != null && request.Keys.Keys.Count > 0)
{
foreach (DictionaryEntry item in request.Keys)
{
if (!(item.Key + "").Contains("{"))
{
ht["{" + item.Key + "}"] = item.Value + "";
}
else
{
ht[item.Key] = item.Value + "";
}
}
}
if (request.ActionStep != null)
{
ht["ActionStep"] = request.ActionStep;
}
return ht;
}
好了,经过这么改造,写代码就更愉悦了。
然而,看过盗梦空间吗?陀螺还在转,所以梦还没醒来……回到现实,代码还是那样写……
下面是改进之后编程的写法,请仔细观察和最开始代码的不同之处。
/// <summary>
/// 获取数据
/// </summary>
private bool GetData()
{
var qq = new DsRequest();
qq.DataSetName = "DSGetData";
qq.TableNames = "T01";
qq.Keys["UserName"]=AppInfo.UserName; //我知道Keys里面都是关键字,所以大括号{}我不用在这加
var result = DataSource.GetDataSet(qq);
/* 取数成功后拿到数据源 */
if (result.IsSuccess)
{
DataTable dt = result.DataTable; //我直接把返回的数据放到了返回类的DataTable属性中了,因为使用频繁,所以这样不是更好吗
}
/* 返回结果 */
return result.IsSuccess;
}
/// <summary>
/// 保存数据
/// </summary>
private bool Save(List<Act> actionStep)
{
/* 判断是否有修改数据 */
var qq = new DsRequest();
qq.DataSetName = "DSGetData";
qq.TableNames = "T01";
qq.ActionStep = new List<Act> { Act.CommitEdit };
var result = DataSource.UpdateDataSet(qq);
/* 若没有修改数据,返回 */
if (!result.IsChanged) { return true; }
/* 询问用户保存数据 */
if (actionStep.Contains(Act.AskIsUpdate))
{
qq.ActionStep = new List<Act> { Act.AskIsUpdate };
result = DataSource.UpdateDataSet(qq);
if (result.IsUpdate == DsUpdateState.Cancel) { return false; } //Cancel取消
if (result.IsUpdate == DsUpdateState.No) { return true; } //No否
actionStep.Remove(Act.AskIsUpdate);
}
/* 保存数据 */
qq.ActionStep = actionStep;
return DataSource.UpdateDataSet(qq).IsSuccess;
}
上面代码大家都懂,不需要解读吧。
那么问题又来了,我们的 DataSource.GetDataSet() 方法期望一个 Hashtable 的参数,这样改造成本是不是大了,我们以前已经开发了上百个程序了,都要改吗?
回到最初我们学习的黄皮书,方法的重载是什么,让我们一起读,chong zai,很好。
1、请求参数原来是一个 Hashtable,我们把它改成一个结构明确的类
/// <summary>
/// DataSource操作请求类
/// </summary>
public class DsRequest
{
/// <summary>
/// 数据集名
/// </summary>
public string DataSetName;
/// <summary>
/// 逻辑表名,多个表用英文逗号分隔
/// </summary>
public string TableNames;
/// <summary>
/// 关键字
/// </summary>
public Hashtable Keys = new Hashtable();
/// <summary>
/// 操作部骤
/// </summary>
public List<Act> ActionStep;
}
2、请求结果原来也是Hashtable,我们也把它改成一个结构明确的类
复制代码
/// <summary>
/// DataSource操作结果类
/// </summary>
public class DsResponse
{
/// <summary>
/// 是否成功
/// </summary>
public bool IsSuccess;
/// <summary>
/// 数据源是否改变
/// </summary>
public bool IsChanged;
/// <summary>
/// 是否需要保存
/// </summary>
public DsUpdateState IsUpdate;
/// <summary>
/// 是否有必录项为空
/// </summary>
public bool IsEmpty;
/// <summary>
/// 结果DataSet
/// </summary>
public DataSet DataSet;
/// <summary>
/// 结果DataTable
/// </summary>
public DataTable DataTable;
/// <summary>
/// 首行首列值
/// </summary>
public object Value;
}
其中是否需要保存之前我们看到返回的情况有-1、0、1,不直观,我们又定义了一个枚举,Yes就是保存,No就是不保存,不好吗?
复制代码
/// <summary>
/// 访问用户是否保存数据时的结果枚举
/// </summary>
public enum DsUpdateState
{
/// <summary>
/// 是
/// </summary>
Yes = 1,
/// <summary>
/// 否
/// </summary>
No = 0,
/// <summary>
/// 用户取消
/// </summary>
Cancel = -1
}
好了,请求类和返回类都定义好了,我们来看看如何请求,请求回来如何使用。
破解说明中的 hosts 文件为:C:\windows\system32\drivers\etc\hosts win8 及以上系统对系统文件有保护,无法直接用记事本修改保存,可修改后另存到桌面,然后覆盖。
港港说的很对。个人看法:这个根据实际情况来判断,这里只是举了个例子,放到了第一列上。其实只要放到任一个不能编辑的列上即可。
扫戴斯乃~
一张图看懂这三个函数
个人一点小看法: 1、使控件失去焦点:如果本来焦点就在当前行的第一列,那这个方法就不起作用了?
个人几点看法:
1、我认为 AfterAssemble() 中只要是出错,都设置 e.Cancel=True,因为可能取数或其它初始化动作失败了,如果窗口还能打开可能会造成操作异常或数据异常。
2、WnGrid.IsAllowEdit 设置时不要忘记权限,否则原来没有 Edit 权限也可能变得可以修改了。
3、110119120122 这是一个电话还是 4 个电话?
补充一下,类似的排序函数有这三个:
ROW_NUMBER():没有重复值的排序(即使两条记录相同,序号也不重复的),不会有同名次。
DENSE_RANK():连续的排序,会出现两个第二名但后面仍然跟着第三名。
RANK():跳跃排序,会出现两个第二名接下来就是第四名,(没有第三名),用于成绩排名。
有的朋友用过一段时间后发现不能用了,这时一般是激活失效了,最简单的方法就是关闭 SQL 后段网再打开 SQL,从菜单上点 SQLPrompt 菜单,会自动恢复激活,如果还不行就段网重新根据步骤激活一次。
楼主好帅,爱你哦!
重装系统时可备份之前的历史记录:
C:\Users\用户名\AppData\Local\Red Gate\SQL Prompt 8\SavedTabs.db
听起来像是疯了。
没疯。为了使用 await,把 Typescript 编译之后再用 Babel 转译一道的人才是疯了。
啥玩意?Typescript 不支持 await?
下个版本就支持了。
我已经无话可说了。
你看其实很简单。用 Typescript 写代码,用 Fetch 发起异步请求,所有代码编译成 ES6,然后用上 Babel 的 stage–3 配置项,把 ES6 转译成 ES5。所有代码用 SystemJS 加载。如果你用不了 Fetch,就加个 polyfill,或者用 Bluebird、Request 或者 Axios,这样你就可以用 await 来处理 Promise 了。
看了我们对于「简单」的理解是不同的。好吧,有了这些,我终于可以获取数据然后用 React 展示数据了,对吧?
你的网页需要处理状态变更吗?
唔,不用吧。我只是想展示数据。
那就好,不然我就得跟你解释 Flux,以及 Flux 的一些实现,比如 Flummox、Alt、Fluxible。不过说真的你应该用 Redux。
你说的这些我就当耳旁风了。再说一次,我只想展示数据。
这样啊,如果你只是想展示数据,其实你不需要 React。你只需要一个模板引擎。
你逗我呢?
我只是告诉你你可以用什么技术。
别说了,真的。
我想说,即使只是用一个模板引擎,我还是会用 Typescript + SystemJS + Babel 的。
我只是想在页面上展示数据,你就告诉我用哪个模板引擎就好了。
有很多,你用过哪一个?
额,太久没用了,不记得了。
jTemplates、jQote 还是 PURE?
额,不记得,还有别的么?
Transparency? JSRender? MarkupJS? KnockoutJS? 这一个支持双向绑定。
还有吗?
PlatesJS? jQuery-tmpl? Handlebars? 还有些人在用。
有点像。有哪些跟最后一个比较像的?
Mustache, underscore? 我记得连 Lodash 都有一个模板引擎,不过这是 2014 年的事情了。
额,也许是再新一点的库?
Jade? DustJS?
没用过
DotJS? EJS?
没用过。
Nunjucks? ECT?
没用过。记不起来了,要是你的话,你用哪个?
我应该会用 ES6 原生的模板字符串
我猜猜,只有 ES6 支持。
对的。
需要用 Babel
对的。
需要用 npm 安装
对的。
需要用 Browserify 或者 Webpack,或者 SystemJS
对的。
如果没用 Webpack 的话,我还需要一个任务管理工具。
对的。
但是由于我要用函数式编程和强类型语言,所以我首先要用上 Typescript 或者 Flow。
对的。
如果我要用 await,那我就必须用 Babel 转译。
对的。
然后我就能用上 Fetch、Promise 和各种炫酷的东西。
嗯,别忘了加上 Fetch 的 Polyfill,因为 Safari 不支持 Fetch。
你猜怎么着,我们就聊到这吧。我不做了,我不做 Web 了,我也不想再碰 JS 了。
没事,过不了几年,我们都会用 Elm 或者 WebAssembly 了。
我要回后端去了,我受不这些变动、版本更新、编译和转译了,JS 社区如果觉得有人能跟上它的脚步,那这个社区就是疯了。
我理解你。我建议你去 Python 社区。
为什么?
听说过 Python 3 吗?
完。 译者注:最后一句「听说过 Python 3 吗?」是讽刺 Python 3 发布已经 8 年了,Python 社区却依然在使用 Python 2.7。而 JS 社区正好相反,把还没有实现的语言特性都用到生成环境中了!
那为什么我们不直接在页面里添加 React 的三个依赖文件呢?
不行。你可以从 CDN 加载这些文件,但是你还是要在本地用 Babel 转译。
唉,这么鹾?
是的,你不能在生产环境上运行 babel,你应该在发布到生产环境之前,运行一系列的任务,包括压缩、混淆、内联化 CSS、延迟加载 script……
我懂了我懂了。既然我不能直接用 CDN,那么我应该怎么做?
我会考虑用 Webpack + SystemJS + Babel 来转译 Typescript。
Typescript?我们不是在说 JavaScript 吗?!
Typescript 也是 JavaScript 呀,它比 JS 更好用,是 JS 的超集,它是基于 ES6 的,就是我们刚才谈论的 ES6,你还记得吧。
ES2016+ 已经是 ES6 的超集了,怎么又冒出来一个 Typescript?
是这样的,Typescript 能让我们写出「强类型」的 JS,从而减少运行时的错误。2016 年,我们应该让 JS 支持强类型了。
显然 Typescript 可以做到。
Flow 也可以做到,区别是 Typescript 需要编译,而 Flow 只是检查语法。
唉,Flow 是?
是一个静态类型检查器,就是 Facebook 的人写的。使用 OCaml 写的,函数式编程很叼的。
OCaml?函数式编程?
如今大牛都用这些东西,都 2016 年了,你懂的,函数式编程、高阶函数、柯里化、纯函数这些概念。
不知道你在说什么。
一开始大家都不知道。这么说吧,你只需要知道函数式编程比面向对象编程厉害,2016 年我们就指着函数式编程了。
等下,我大学里学过面向对象编程,当时我觉得它还不错。
Java 在被 Oracle 买下来之前也挺不错啊。我的意思是,面向对象以前是不错,现在依然有人用它,但是现在所有人都发觉状态变换是很难维护的,所以大家都开始用「不可变对象」和函数式编程了。Haskell 的人已经用这套东西用了很久了,不过幸运的是 Web 开发领域里有 Ramda 这样的库,让我们用 JS 就可以进行函数式编程了。
你刚刚是不是又抛出了几个名词?Ramnda 又是什么?
不是 Ramnda,是 Ramda,跟 Lambda 表达式有点像。是 David Chambers 写的库。
谁?
David Chambers,大神一个。blablabla
我不得不打断你一下了。这些东西看起来都不错,但是我觉得它们都太复杂,而且没必要。我只是想获取数据然后展示,我很确定这种情况下我不需要掌握这些知识。 回到 React 吧,用 React 我怎么从服务器获取数据?
额,React 没有提供这个功能,你只能用 React 展示数据。
服了啊。那我怎么获取数据?
你用 Fetch API 就可以了。
啥玩意?这个 API 的名字很烂啊。
我也觉得是啊。Fetch API 是浏览器提供的异步请求接口。
哦,那不就是 AJAX。
AJAX 只是使用 XMLHttpRequest 对象,但是 Fetch API 可以让你用 Promise 风格来发起异步请求,帮你摆脱「回调地狱」。
回调地狱?
是的,每次你发起一个异步请求,就得等待它响应。这时你就得在函数里使用一个函数,这种嵌套调用就是回调地狱。
好吧。Promise 解决了这个问题么?
是的。用 Promise 来管理回调,你就可以写出更易读的代码,更容易测试的代码。甚至可以同时发起多个请求,然后等待它们全部返回。
Fetch 也能做到吗?
是的。但前提是你的用户使用了新版的浏览器,不然的话你就需要加一个 Fetch 的「polyfill」,或者使用 Request、Bluebird 或者 Axios 这些库。
天呐我到底需要多少个库?
这是 JS,同一件事情有上千个库在做。我们了解库,而且我们有最好的库,我们有海量的库,要什么有什么。
你刚才说的几个库都是干什么的?
这几个库操作 XMLHttpRequest 然后返回 Promise 对象。
好像 jQuery 的 ajax 方法做的是同样的事吧……
从 2016 年起我们就不用 jQuery 了。用 Fetch,大不了加个 Polyfill,要不然用 Bluebird、Request 或者 Axios 都行。然后用 await 和 async 管理 Promise,这样才能控制好异步任务。
这是你第三次说 await 了,那是什么东西?
await 能让你拦住一个异步调用,让你更好地控制异步返回的数据,大大增强了代码的可读性。await 非常好用,你只需要在 Babel 里添加 stage–3 配置,或者添加 syntax-async-functions 和 transform-async-to-generator 插件就可以了。
这里是视频教程:http://down.lttc.cn/Video/20170610_SQL_Server_.avi数据库结构差异对比