.net 动态编译解决考勤计算问题
由于公司实施SAP HR项目,但是SAP HR对考勤功能真的太弱化了,直接从考勤机上读取的原始打卡记录不能直接传输到HR系统里面,因为SAP HR不能识别那些多余的打卡记录,而且必须把打卡记录进行成组标记(P10,P20),以上标红色的是SAP HR顾问给我的反馈信息。
这样以来,必须开发一套算法来把多余的打卡记录进行过滤掉,然后标记上是P10还是P20,这样以来,HR系统在做时间评估时才不会出现异常情况。
需求已经明确,那么就是设计开发的问题,要开发该功能,需要用到的资源:
1、考勤的排班数据
2、原始打卡数据
3、取原始打卡数据的算法
然后就是确定该功能在我们的外围基础数据平台开发(外围系统是用.net开发的)
由于我们公司的考勤计算方式可能会经常有变化,因为不能把打卡数据的算法写死到代码里面,这样有两种解决方案:1是用侟储过程 2是用动态编译
考虑到以后数据库的迁移问题,最终采取.net动态编译方式来处理该问题
具体的实现思想如下:
1、把算法代码存储在数据库表中
2、新建一个计算考勤的静态类,类里面定义一个计算考勤的静态方法,传入参数为两上Table类型,一个为排班表,一个为原始打卡记录表,返回参数也
为DataTable内型,为计算完成后的结果数据,把该段代码保存在一个静态变量里面。
3、调用计算方法时,把静态类的代码加上代算法代码编译成动态类。
4、利用反射技术,调用计算方法,返回结果。
关键性代码如下:
动态编译类:
DynCompiler.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Reflection;
using System.Data; namespace EDICLibrary
{
public class DynCompiler:IDisposable
{ CodeDomProvider _codeprovide;
CompilerParameters _parameters;
CompilerResults _result = null;
MethodInfo _method = null;
Object _instance = null; public DynCompiler()
{
_codeprovide = new CSharpCodeProvider();
_parameters = new CompilerParameters();
_parameters.GenerateExecutable = false;
_parameters.GenerateInMemory = true;
_parameters.ReferencedAssemblies.Add("System.dll");
_parameters.ReferencedAssemblies.Add("System.Data.dll");
_parameters.ReferencedAssemblies.Add("System.Xml.dll");
} public bool SourceCompiler(string source, out string outputMsg)
{
outputMsg = "";
StringBuilder sbout = new StringBuilder();
StringBuilder sb = new StringBuilder();
if (string.IsNullOrEmpty(source))
{
outputMsg = "源代码不能为空!";
return false;
}
else
{ sb.AppendLine("using System;");
sb.AppendLine("using System.Collections.Generic;");
sb.AppendLine("using System.Text;");
sb.AppendLine("using System.Data;");
sb.AppendLine ("using System.Xml;");
sb.AppendLine("namespace JMCompiler");
sb.AppendLine("{");
sb.AppendLine("public class DynCompilerHelper");
sb.AppendLine("{");
sb.AppendLine("public DataTable Calculate(DataTable dtShiftInfo,DataTable dtTimes)");
sb.AppendLine("{");
sb.Append(source);
sb.Append("}");
sb.AppendLine("}");
sb.AppendLine("}");
}
_result = _codeprovide.CompileAssemblyFromSource(_parameters, sb.ToString());
if (_result.Errors.HasErrors)
{
foreach (string str in _result.Output)
{
sbout.AppendLine(str);
}
outputMsg = sbout.ToString();
return false;
}
else
{
Type _type = _result.CompiledAssembly.GetType("JMCompiler.DynCompilerHelper");
_instance = Activator.CreateInstance(_type);
_method = _type.GetMethod("Calculate",new Type[]{typeof(DataTable),typeof (DataTable)});
outputMsg = "编译成功";
return true;
} } public object GetReturnResult(List<DataTable> parameters)
{ if (_method == null)
{
throw new Exception ("未进行代码编译");
}
return _method.Invoke(_instance, parameters.ToArray());
} #region IDisposable 成员 public void Dispose()
{
_codeprovide = null;
_parameters = null;
_result = null;
_method = null;
_instance = null;
} #endregion
}
}
计算考勤类:
AttdCalculate.cs
public class AttdCalculate
{
/// <summary>
/// 计算考勤
/// </summary>
/// <param name="source">计算考勤算法代码</param>
/// <param name="dtShiftInfo">排班信息</param>
/// <param name="dtTimes">原始打卡的数据</param>
/// <param name="msg">输出信息</param>
/// <returns>计算后的结果表</returns>
public static DataTable Calculate(string source, DataTable dtShiftInfo, DataTable dtTimes, out string msg)
{
if (string.IsNullOrEmpty(source))
{
msg = "考勤计算逻辑不能为空";
return new DataTable();
}
DynCompiler complier = new DynCompiler();
string output;
bool result = complier.SourceCompiler(source, out output);
List<DataTable> lstData = new List<DataTable>();
lstData.Add(dtShiftInfo);
lstData.Add(dtTimes);
if (result)
{
msg = "计算成功";
return (DataTable)complier.GetReturnResult(lstData);
}
else
{ msg = output;
return new DataTable();
}
} }
考勤调用代码
//计算公式
string Source = string.Empty;
//获取计算工式
Source = <获取计算工式的方法>
string msg;
//获取考勤数据 DataTable dtResult = MIS.Util.AttdCalculate.Calculate(Source, dtShiftInfo, dtTimes, out msg);
在写这篇文章的时候,开发的功能还没有投入到正式运行,但是经过最近一段时候的测试来看,没有任何问题。
.net 动态编译解决考勤计算问题的更多相关文章
- Java_java动态编译整个项目,解决jar包找不到问题
java动态编译整个项目,解决jar包找不到问题原文:http://itzyx.com/index.php/javac/ 动态将java文件编译为class文件解决方案:将temp\sdl\src目录 ...
- (转载)JAVA动态编译--字节代码的操纵
在一般的Java应用开发过程中,开发人员使用Java的方式比较简单.打开惯用的IDE,编写Java源代码,再利用IDE提供的功能直接运行Java 程序就可以了.这种开发模式背后的过程是:开发人员编写的 ...
- JIT(动态编译)和AOT(静态编译)编译技术比较
Java 应用程序的性能经常成为开发社区中的讨论热点.因为该语言的设计初衷是使用解释的方式支持应用程序的可移植性目标,早期 Java 运行时所提供的性能级别远低于 C 和 C++ 之类的编译语言.尽管 ...
- 分享基于.NET动态编译&Newtonsoft.Json封装实现JSON转换器(JsonConverter)原理及JSON操作技巧
看文章标题就知道,本文的主题就是关于JSON,JSON转换器(JsonConverter)具有将C#定义的类源代码直接转换成对应的JSON字符串,以及将JSON字符串转换成对应的C#定义的类源代码,而 ...
- Java_动态编译总结
不多说直接上代码: 动态编译的主类: package com.lkb.autoCode.util; import com.lkb.autoCode.constant.AutoCodeConstant; ...
- .NET中的动态编译
代码的动态编译并执行是一个.NET平台提供给我们的很强大的工具用以灵活扩展(当然是面对内部开发人员)复杂而无法估算的逻辑,并通过一些额外的代码来扩展我们已有 的应用程序.这在很大程度上给我们提供了另外 ...
- Java_JAVA6动态编译的问题
摘自:http://www.iteye.com/problems/14909 在使用JAVA6动态编译时遇到的一个问题,动态编译方法已经写就.通过main方法调用的动态编译时,编译通过,并可以使用编译 ...
- 关于cshtml中的js对动态编译支持的问题
问题:MVC4中支持对ViewBag.ViewDate等的动态编译,但是在js中对它的支持就是有问题.虽然是可以动态编译,但是动态编译之后,断点无法获取. $.getJSON("/api/A ...
- ASP.NET 动态编译、预编译和 WebDeployment 项目(转)
概述 在 Web 服务器上,既可以部署源文件,也可以部署编译后程序集. 若部署源文件,则当用户访问时,Web 应用程序会被动态编译,并缓存该程序集,以便下次访问. 否则,若部署程序集,Web 应用程序 ...
随机推荐
- java数据结构之列表——ArrayList,LinkedList,比较
刚看完<数据结构与算法分析java语言描述>的第3章中的表,下面回忆下主要知识点,主要说明各列表之间的关系,以及各自的优缺点.其中牵涉到内部类和嵌套类. 1 Collection APIp ...
- 【教程】【FLEX】#003 自定义事件、模块间通讯
本篇笔记,主要阐明 事件是如何创建 和 如何使用自定义事件达到模块之间通讯 的效果. 句子解释: 什么叫做模块之间的通讯呢?? 简单点说,就是两个模块之间可以互相传数据. A模块 可以接收到 B模块的 ...
- Spring 3.0以后版本的定时任务
自主开发的定时任务工具,spring task,可以将它比作一个轻量级的Quartz,而且使用起来很简单,除spring相关的包外不需要额外的包,而且支持注解和配置文件两种 <beans xml ...
- 洛谷P1467 循环数 Runaround Numbers
P1467 循环数 Runaround Numbers 89通过 233提交 题目提供者该用户不存在 标签USACO 难度普及/提高- 提交 讨论 题解 最新讨论 暂时没有讨论 题目描述 循环数是 ...
- aspxgridView,Repeater增加自动序号列
第一种方式,直接在Aspx页面GridView模板列中.这种的缺点是到第二页分页时又重新开始了. <asp:TemplateField HeaderText="序号" Ins ...
- 七、TCP/IP协议
1.定义: TCP/IP模型也被称作DoD模型(Department of Defense Model).TCP/IP字面上代表了两个协议:TCP(传输控制协议)和IP(网际协议). TCP/IP协议 ...
- 1.4Linux内核版本号的定义规则
Linux内核版本号的组成: (1)主版本号: (2)次版本号: (3)修订版本号: (4)微调版本号: (5)为特定的Linux系统特别调校的描述: 例子:2.6.29.7-flykernel-12 ...
- ASP.NET MVC5 高级编程 第5章 表单和HTML辅助方法
参考资料<ASP.NET MVC5 高级编程>第5版 第5章 表单和HTML辅助方法 5.1 表单的使用 5.1.1 action 和 method 特性 默认情况下,表单发送的是 HTT ...
- 快速解决Canvas.toDataURL 图片跨域的问题
出现Canvas.toDataURL 图片跨域问题怎么解决呢?下面小编就为大家带来一篇Canvas.toDataURL 图片跨域问题的快速解决方法.一起跟随小编过来看看吧 如题,在将页面的图片地址进行 ...
- 【项目相关】MVC中使用WebUploader进行图片预览上传以及编辑
项目中需要用到多图片上传功能,于是在百度搜了一下,首先使用了kissy uploader,是由阿里前端工程师们发起创建的一个开源 JS 框架中的一个上传组件...但,后面问题出现了. 在对添加的信息进 ...