quartznet 


  上篇说到quartznet这个东东,topshelf+quartznet有很多不错的文章,可以查看七七同学的文章(http://www.cnblogs.com/jys509/p/4628926.html)。这里我主要说说cron表达式,如果玩过linux下定时任务的肯定不陌生。

  官方英文介绍地址:http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/crontrigger.html

  cron expressions 整体上还是非常容易理解的,只有一点需要注意:"?"号的用法,看下文可以知道“?”可以用在 day of month 和 day of week中,他主要是为了解决如下场景,如:每月的1号的每小时的31分钟,正确的表达式是:* 31 * 1 * ?,而不能是:* 31 * 1 * *,因为这样代表每周的任意一天。

  由7段构成:秒 分 时 日 月 星期 年(可选)
  "-" :表示范围  MON-WED表示星期一到星期三
  "," :表示列举 MON,WEB表示星期一和星期三
  "*" :表是“每”,每月,每天,每周,每年等
  "/" :表示增量:0/15(处于分钟段里面) 每15分钟,在0分以后开始,3/20 每20分钟,从3分钟以后开始
  "?" :只能出现在日,星期段里面,表示不指定具体的值
  "L" :只能出现在日,星期段里面,是Last的缩写,一个月的最后一天,一个星期的最后一天(星期六)
  "W" :表示工作日,距离给定值最近的工作日
  "#" :表示一个月的第几个星期几,例如:"6#3"表示每个月的第三个星期五(1=SUN...6=FRI,7=SAT)

  官方实例

Expression Meaning
0 0 12 * * ? 每天中午12点触发
0 15 10 ? * * 每天上午10:15触发
0 15 10 * * ? 每天上午10:15触发
0 15 10 * * ? * 每天上午10:15触发
0 15 10 * * ? 2005 2005年的每天上午10:15触发
0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发
0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发
0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发
0 15 10 ? * MON-FRI 周一至周五的上午10:15触发
0 15 10 15 * ? 每月15日上午10:15触发
0 15 10 L * ? 每月最后一日的上午10:15触发
0 15 10 L-2 * ? Fire at 10:15am on the 2nd-to-last last day of every month
0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发
0 15 10 ? * 6L Fire at 10:15am on the last Friday of every month
0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发
0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发
0 0 12 1/5 * ? Fire at 12pm (noon) every 5 days every month, starting on the first day of the month.
0 11 11 11 11 ? Fire every November 11th at 11:11am.

  

 class Program
{
static void Main(string[] args)
{
log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log4net.config"));
HostFactory.Run(x =>
{
x.UseLog4Net();
x.Service<ServiceRunner>();
x.RunAsLocalSystem(); x.SetDescription("Windows服务导出数据");
x.SetDisplayName("QuartzTopShelf");
x.SetServiceName("QuartzTopShelfService");
x.EnablePauseAndContinue(); });
}
}
 public class ServiceRunner : ServiceControl, ServiceSuspend
{
private readonly IScheduler scheduler; public ServiceRunner()
{
scheduler = StdSchedulerFactory.GetDefaultScheduler();
} public bool Start(HostControl hostControl)
{
scheduler.Start();
return true;
} public bool Stop(HostControl hostControl)
{
scheduler.Shutdown(false);
return true;
} public bool Continue(HostControl hostControl)
{
scheduler.ResumeAll();
return true;
} public bool Pause(HostControl hostControl)
{
scheduler.PauseAll();
return true;
} }

 Dapper


  Dapper是一款轻量级ORM工具(Github)。如果你在小的项目中,使用Entity Framework、NHibernate 来处理大数据访问及关系映射,未免有点杀鸡用牛刀。你又觉得ORM省时省力,这时Dapper 将是你不二的选择。

Dapper优势:

  1. 轻量。只有一个文件(SqlMapper.cs),编译完成之后只有120k(好象是变胖了)
  2. 速度快。Dapper的速度接近与IDataReader,取列表的数据超过了DataTable。
  3. 支持多种数据库。Dapper可以在所有Ado.net Providers下工作,包括sqlite, sqlce, firebird, oracle, MySQL, PostgreSQL and SQL Server
  4. 可以映射一对一,一对多,多对多等多种关系。
  5. 性能高。通过Emit反射IDataReader的序列队列,来快速的得到和产生对象,性能不错。
  6. 支持FrameWork2.0,3.0,3.5,4.0,4.5

上篇已经说过我用dapper的原因,就是为了方便而已。(使用dapper可以不去考虑你的数据库是sqlserver还是mysql,上层只需要配置一下连接串就行,方便的很)

直接上代码(用的是仓储模式):

IRepository.cs  

  public interface IRepository<TEntity> where TEntity : class
{
object Insert(TEntity entity); void Insert(IList<TEntity> list); bool Update(TEntity entity); bool Delete(TEntity entity); TEntity GetEntity(int id); int GetCount(object predicate); /// <summary>
/// 分页获取数据
/// </summary>
/// <param name="predicate"></param>
/// <param name="page">页数</param>
/// <param name="resultsPerPage">每页数量</param>
/// <param name="sort">排序</param>
/// <returns></returns>
IList<TEntity> GetPageList(object predicate, int pageIndex, int pageSize, IList<ISort> sort); }

Repository.cs

 public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
private string _connName = null;
/// <summary>
/// 数据库连接名称
/// </summary>
public string connName { set { _connName = value; } } public object Insert(TEntity entity)
{
using (var db = DbFactory.GetDatabase(_connName))
{ return db.Insert(entity);
}
} public void Insert(IList<TEntity> list)
{
using (var db = DbFactory.GetDatabase(_connName))
{
db.Insert<TEntity>(list);
}
} public bool Update(TEntity entity)
{
using (var db = DbFactory.GetDatabase(_connName))
{
return db.Update(entity);
}
} public bool Delete(TEntity entity)
{
using (var db = DbFactory.GetDatabase(_connName))
{
return db.Delete(entity);
}
} public IList<TEntity> GetList()
{
using (var db = DbFactory.GetDatabase(_connName))
{
return db.GetList<TEntity>().ToList();
}
}
public IList<TEntity> GetList(object predicate, IList<ISort> sort = null)
{
using (var db = DbFactory.GetDatabase(_connName))
{
return db.GetList<TEntity>(predicate, sort).ToList();
} }
public IList<TEntity> GetPageList(object predicate, int pageIndex, int pageSize, IList<ISort> sort)
{
using (var db = DbFactory.GetDatabase(_connName))
{
return db.GetPage<TEntity>(predicate, sort, pageIndex, pageSize).ToList();
}
} public int GetCount(object predicate)
{
using (var db = DbFactory.GetDatabase(_connName))
{
return db.Count<TEntity>(predicate);
}
} public TEntity GetEntity(int id)
{
using (var db = DbFactory.GetDatabase(_connName))
{
return db.Get<TEntity>(id);
}
}
public TEntity GetEntity(string id)
{
using (var db = DbFactory.GetDatabase(_connName))
{
return db.Get<TEntity>(id);
}
}
}

  DbFactory.CS

 public class DbFactory
{
/// 得到web.config里配置项的数据库连接字符串。
private static readonly ConnectionStringSettings _settings = ConfigurationManager.ConnectionStrings["XX"]; public static IDbConnection GetDbConnection(string connName = null)
{
ConnectionStringSettings settings = _settings;
if (connName != null)
settings = ConfigurationManager.ConnectionStrings[connName];
if (settings == null)
throw new Exception("数据库连接字符串不能为空!");
DbServerType type = (DbServerType)Enum.Parse(typeof(DbServerType), settings.ProviderName);
return GetDbConnection(settings.ConnectionString, type);
} public static IDbConnection GetDbConnection(string connStr, DbServerType type)
{
if (string.IsNullOrEmpty(connStr)) throw new Exception("数据库连接字符串不能为空!"); IDbConnection conn = null;
switch (type)
{
case DbServerType.MsSqlServer:
conn = new SqlConnection(connStr);
break;
case DbServerType.MySQL:
conn = new MySqlConnection(connStr);
break;
case DbServerType.SQLite:
case DbServerType.Orcale:
case DbServerType.DB2:
case DbServerType.MongoDB:
default:
throw new NotImplementedException("尚未实现对该数据库的支持!");
}
conn.Open();
return conn;
} public static IDatabase GetDatabase(string connName = null)
{
ConnectionStringSettings settings = _settings;
if (connName != null)
settings = ConfigurationManager.ConnectionStrings[connName];
if (settings == null)
throw new Exception("数据库连接字符串不能为空!");
DbServerType type = (DbServerType)Enum.Parse(typeof(DbServerType), settings.ProviderName);
return GetDatabase(settings.ConnectionString, type);
} public static IDatabase GetDatabase(string connStr, DbServerType type)
{
if (string.IsNullOrEmpty(connStr)) throw new Exception("数据库连接字符串不能为空!"); IDbConnection conn = null;
IDapperExtensionsConfiguration config = null;
ISqlGenerator sqlGenerator = null; switch (type)
{
case DbServerType.MsSqlServer:
conn = new SqlConnection(connStr);
config = new DapperExtensionsConfiguration(typeof(AutoClassMapper<>), new List<Assembly>(), new SqlServerDialect());
sqlGenerator = new SqlGeneratorImpl(config);
break;
case DbServerType.MySQL:
conn = new MySqlConnection(connStr);
config = new DapperExtensionsConfiguration(typeof(AutoClassMapper<>), new List<Assembly>(), new MySqlDialect());
sqlGenerator = new SqlGeneratorImpl(config);
break;
case DbServerType.SQLite:
case DbServerType.Orcale:
case DbServerType.DB2:
case DbServerType.MongoDB:
default:
throw new NotImplementedException("尚未实现对该数据库的支持!");
}
return new Database(conn, sqlGenerator);
}
}

NPOI


  npoi没什么好说的,直接nuget上下载dll,就可以使用了,有兴趣的可以下载源码看看,用它做一些excel的样式也是很方便的。   

  public static class NPOIHelper
{
public static void ExportToFile(DataSet dataSet, string fileFullPath)
{
List<DataTable> dts = new List<DataTable>();
foreach (DataTable dt in dataSet.Tables) dts.Add(dt);
ExportToFile(dts, fileFullPath);
}
public static void ExportToFile(DataTable dataTable, string fileFullPath)
{
List<DataTable> dts = new List<DataTable>();
dts.Add(dataTable);
ExportToFile(dts, fileFullPath);
}
public static void ExportToFile(IEnumerable<DataTable> dataTables, string fileFullPath)
{
IWorkbook workbook = new XSSFWorkbook();
int i = ;
foreach (DataTable dt in dataTables)
{
string sheetName = string.IsNullOrEmpty(dt.TableName)
? "Sheet " + (++i).ToString()
: dt.TableName;
ISheet sheet = workbook.CreateSheet(sheetName); IRow headerRow = sheet.CreateRow();
for (int j = ; j < dt.Columns.Count; j++)
{
string columnName = string.IsNullOrEmpty(dt.Columns[j].ColumnName)
? "Column " + j.ToString()
: dt.Columns[j].ColumnName;
headerRow.CreateCell(j).SetCellValue(columnName);
} for (int a = ; a < dt.Rows.Count; a++)
{
DataRow dr = dt.Rows[a];
IRow row = sheet.CreateRow(a + );
for (int b = ; b < dt.Columns.Count; b++)
{
row.CreateCell(b).SetCellValue(dr[b] != DBNull.Value ? dr[b].ToString() : string.Empty);
}
}
} using (FileStream fs = File.Create(fileFullPath))
{
workbook.Write(fs);
}
} public static List<DataTable> GetDataTablesFrom(string xlsxFile)
{
if (!File.Exists(xlsxFile))
throw new FileNotFoundException("文件不存在"); List<DataTable> result = new List<DataTable>();
Stream stream = new MemoryStream(File.ReadAllBytes(xlsxFile));
IWorkbook workbook = new XSSFWorkbook(stream);
for (int i = ; i < workbook.NumberOfSheets; i++)
{
DataTable dt = new DataTable();
ISheet sheet = workbook.GetSheetAt(i);
IRow headerRow = sheet.GetRow(); int cellCount = headerRow.LastCellNum;
for (int j = headerRow.FirstCellNum; j < cellCount; j++)
{
DataColumn column = new DataColumn(headerRow.GetCell(j).StringCellValue);
dt.Columns.Add(column);
} int rowCount = sheet.LastRowNum;
for (int a = (sheet.FirstRowNum + ); a < rowCount; a++)
{
IRow row = sheet.GetRow(a);
if (row == null) continue; DataRow dr = dt.NewRow();
for (int b = row.FirstCellNum; b < cellCount; b++)
{
if (row.GetCell(b) == null) continue;
dr[b] = row.GetCell(b).ToString();
} dt.Rows.Add(dr);
}
result.Add(dt);
}
stream.Close(); return result;
}
}

   好了,就说到这里吧,欢迎拍砖。

  

Topshelf+Quartz.net+Dapper+Npoi(二)的更多相关文章

  1. Topshelf+Quartz.net+Dapper+Npoi(一)

    背景 前段时间公司有个需求(每天给业务导出一批数据,以excel的形式通过邮件发送给他).A说:直接写个服务,判断等于某个时间点,执行一下sql语句,生成excel,写个EmaiHelper发送给他不 ...

  2. .net core+topshelf+quartz创建windows定时任务服务

    .net core+topshelf+quartz创建windows定时任务服务 准备工作 创建.net core 控制台应用程序,这里不做过多介绍 添加TopShelf包:TopShelf: 添加Q ...

  3. Dapper学习 - Dapper.Rainbow(二) - Update/Delete

    上一篇介绍了Rainbow的Create方法, 这里就来介绍一下Update方法吧, 毕竟新增和修改是双胞兄弟嘛. 一.Update 1. 测试代码: var conStr = Configurati ...

  4. Spring的quartz定时器重复执行二次的问题解决

    Spring的quartz定时器同一时刻重复执行二次的问题解决 最近用Spring的quartz定时器的时候,发现到时间后,任务总是重复执行两次,在tomcat或jboss下都如此. 打印出他们的ha ...

  5. 轻量级ORM框架Dapper应用二:使用Dapper实现CURD操作

    在上一篇文章中,讲解了如何安装Dapper,这篇文章中将会讲解如何使用Dapper使用CURD操作. 例子中使用到的实体类定义如下: using System; using System.Collec ...

  6. Topshelf+Quartz在.Net Core框架下的实现

    在我们日常开发工作中,经常会运用到Quartz+Topshelf组件的组合来开发一些定时任务.那么在.Net Core下如何去使用呢?我自己尝试搭建了一个测试项目,过程中遇到了以下一些问题: Quar ...

  7. TopShelf+Quartz.net 实现window服务

    Quartz.NET官网   TopShelf 网址 代码地址:https://github.com/SeaLee02/ProjectDemo/tree/master/WindowServerDemo ...

  8. Quartz.NET总结(二)CronTrigger和Cron表达式

    Quartz.NET的任务调度,主要就是依靠CronTrigger和Cron表达式.Cron是已经在UNIX存在了很长一段时间,它有着强大和可靠的调度能力.CronTrigger类也正是是基于Cron ...

  9. TopShelf&Quartz.Net实现多任务的值守

    很多时候,我们需要为一个服务器安装一堆的服务,来监控各种数据. 在windows服务器里,我们会部署专门的Quartz.Net多任务轮询服务. 同时,我们针对不同的任务制作专门的***Job.dll, ...

随机推荐

  1. centos6 install cobbler

    cobbler 安装   一:定义yum源 wget -c -O CentOS-Base.repo http://mirrors.163.com/.help/CentOS6-Base-163.repo ...

  2. URAL 1732. Ministry of Truth ( KMP 多模式串匹配 )

    问在第一个串中删掉几个字符能否得到第二个串.注意在第二个串中不连续的单词在第一个串中也必须不连续. 一组数据: Input: abababbbbababbb aba ab Output: I HAVE ...

  3. UVa 1445 - Cubist Artwork

    统计正面看高度为i的竖条个数为cnt1[i], 统计侧面看高度为i的竖条个数为cnt2[i]: ans = sum( i * max( cnt1[i], cnt2[i] ) ); ( 1 <= ...

  4. 软工实践 - 第十九次作业 Alpha 冲刺 (10/10)

    队名:起床一起肝活队 组长博客:https://www.cnblogs.com/dawnduck/p/10046955.htmlz 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 ...

  5. 【bzoj2793】[Poi2012]Vouchers 暴力

    题目描述 考虑正整数集合,现在有n组人依次来取数,假设第i组来了x人,他们每个取的数一定是x的倍数,并且是还剩下的最小的x个.正整数中有m个数被标成了幸运数,问有哪些人取到了幸运数. 输入 第一行一个 ...

  6. 【bzoj4325】NOIP2015 斗地主(&“加强”版) 搜索

    题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...

  7. 2151: 种树 - BZOJ

    Description A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编号1到n.并且每个位置都有一个美观度 ...

  8. 封装的方法--读取任何路径下的properties文件中的值

    概述:我们在做项目时,经常需要从某个properties文件中读取properties文件中的值.现在我封装了一下方法,直接读取配置文件中的值. 代码如下所示: /** * Created by qi ...

  9. mysql索引记

    如果字段是数值型,where 是字符串型,走索引但是,如果字段是字符串型,但是where 是数值型,不走索引

  10. HDU 3853 LOOP (概率DP求期望)

    D - LOOPS Time Limit:5000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit St ...