需求:每隔一段时间存一条数据到Access数据库,数据库文件以日期命名,把这个功能封装以供调用
分解任务:1新建数据库文件 2新建数据库表 3向数据库表中增加数据 4需要有日志记录执行结果 5由于过多的dll不易于传播维护,需要将这些dll封装
参考资料:
关闭ADOX.Catalog创建Access的链接,避免ldb锁定-CSDN博客
创建文件 创建表 插入一条数据即为MyAccess类
public class MyAccess{//保存access的路径private string accessFileFullName;public string AccessFileFullName{get { return accessFileFullName; }set { accessFileFullName = value; }}//在指定目录下创建空白的mdb数据库文件public int CreateAccessDBFile(string strAccessFileName){ADOX.Catalog catalog = new Catalog();if (!File.Exists(strAccessFileName)){try{string strCreate = "Provider=Microsoft.Jet.OleDB.4.0";strCreate += ";Data Source=" + strAccessFileName; // Your *.mdb File,注意扩展名必须为mdb,否则不能插入表strCreate += ";Jet OLEDB:Engine Type=5";strCreate += ";Locale Identifier=0x0804"; // Locale Identifier=0x0804,支持简体中文 catalog.Create(strCreate);// 关闭数据库:(catalog.ActiveConnection as ADODB.Connection).Close();catalog.ActiveConnection = null;catalog = null;accessFileFullName = strAccessFileName;return 1;}catch (Exception ex){accessFileFullName = null;// 关闭数据库:(catalog.ActiveConnection as ADODB.Connection).Close();catalog.ActiveConnection = null;catalog = null;LogHelper.WriteLogError(ex.Message);throw new Exception(string.Format("CreateAccessDBFile Error-->{0}", ex.Message));}}accessFileFullName = strAccessFileName;return 2;}//为mdb数据库文件创建表public bool CreateDBTable(string strTableName, params ADOX.Column[] columns){if (accessFileFullName == null){return false;}ADODB.Connection conn = new ADODB.Connection();ADOX.Catalog catalog = new ADOX.Catalog();try{conn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + accessFileFullName, null, null, -1);catalog.ActiveConnection = conn;//创建一个表格ADOX.Table table = new ADOX.Table();//获取表名table.Name = strTableName;//遍历一个字段的集合,从而添加字段foreach (var column in columns){//如果不是bool类型的,可以为空if (column.Type != DataTypeEnum.adBoolean){//允许空值column.Attributes = ColumnAttributesEnum.adColNullable;}//保存字段 table.Columns.Append(column);}//向数据中添加表 catalog.Tables.Append(table);// 关闭数据库:(catalog.ActiveConnection as ADODB.Connection).Close();catalog.ActiveConnection = null;catalog = null;}catch (Exception ex){// 关闭数据库:(catalog.ActiveConnection as ADODB.Connection).Close();catalog.ActiveConnection = null;catalog = null;LogHelper.WriteLogError(ex.Message);throw new Exception(string.Format("CreateDBTable Error-->{0}", ex.Message));}return true;}//特定格式 增加一行数据public bool AddTestData(string strSN, string strResult, string strTime){if (accessFileFullName == null){return false;}string strConnect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + accessFileFullName;try{// 创建并打开连接using (OleDbConnection conn = new OleDbConnection(strConnect)){conn.Open();string strSql = "INSERT INTO TestInfoBaseSerialNo(SerialNo,TestResult,SystemTime)" + "VALUES (?,?,?)";using (OleDbCommand cmd = new OleDbCommand(strSql, conn)){// 添加参数,并指定数据类型cmd.Parameters.AddWithValue("@SerialNo", strSN);cmd.Parameters.AddWithValue("@TestResult", strResult);cmd.Parameters.AddWithValue("@SystemTime", strTime);// 执行命令int result = cmd.ExecuteNonQuery();if (result >= 1){return true;}else{LogHelper.WriteLogError("OleDbCommand.ExecuteNonQuery 执行失败");return false;}}}}catch (Exception ex){LogHelper.WriteLogError(ex.Message);throw;}}}
调用类
public class QiangSongATEMESBondMyAccess{MyAccess myAccess = new MyAccess();//按照客户要求创建access文件 //按照客户要求创建表 //添加一行数据 SN 时间 测试结果public bool CreateAccessFileCreateTableAddData(string strPath, string strTPName, string strSN, string strResult, string strTime){string strTemp = string.Format("CreateAccessFileCreateTableAddData 开始, 测试程序名={0},SN={1},测试结果={2},测试开始时间={3},路径={4}",strTPName, strSN, strResult, strTime, strPath);LogHelper.WriteLogInfo(strTemp);string strDate = DateTime.Now.ToString("yyyy-MM-dd");string strAccessPath = strPath + strTPName + "@" + strDate + ".mdb";//创建需要数据表的字段ADOX.Column[] userSetColumns ={//这块大家注意数据类型的问题new ADOX.Column(){Name="SerialNo",Type=DataTypeEnum.adVarWChar, DefinedSize=100},new ADOX.Column(){Name="ModelName",Type=DataTypeEnum.adVarWChar, DefinedSize=200},new ADOX.Column(){Name="LotNumber",Type=DataTypeEnum.adVarWChar, DefinedSize=100},new ADOX.Column(){Name="OrderNumber",Type=DataTypeEnum.adVarWChar, DefinedSize=100},new ADOX.Column(){Name="Environment",Type=DataTypeEnum.adVarWChar, DefinedSize=100},new ADOX.Column(){Name="Inspector",Type=DataTypeEnum.adVarWChar, DefinedSize=100},new ADOX.Column(){Name="Customer",Type=DataTypeEnum.adVarWChar, DefinedSize=100},new ADOX.Column(){Name="TestResult",Type=DataTypeEnum.adVarWChar, DefinedSize=50},new ADOX.Column(){Name="ElapsedTime",Type=DataTypeEnum.adVarWChar, DefinedSize=100},new ADOX.Column(){Name="SystemTime",Type=DataTypeEnum.adVarWChar, DefinedSize=100},new ADOX.Column(){Name="RetestTimes",Type=DataTypeEnum.adSmallInt},new ADOX.Column(){Name="FixtureNumber",Type=DataTypeEnum.adInteger},new ADOX.Column(){Name="ChannelNumber",Type=DataTypeEnum.adInteger},};//设置数据表的名称string tableName = "TestInfoBaseSerialNo";try{LogHelper.WriteLogInfo("开始创建access文件");int ret = myAccess.CreateAccessDBFile(strAccessPath);//创建空access文件成功if (ret == 1){//创建access文件成功LogHelper.WriteLogInfo("创建access文件成功,开始创建表和字段");if (myAccess.CreateDBTable(tableName, userSetColumns)){//创建表成功LogHelper.WriteLogInfo("创建表成功,开始增加一行数据");if (myAccess.AddTestData(strSN, strResult, strTime)){LogHelper.WriteLogInfo("增加一行数据成功");return true;}//增加数据失败else{LogHelper.WriteLogInfo("增加一行数据失败");return false;}}//创建表失败else{LogHelper.WriteLogInfo("创建数据库表失败");return false;}}//access文件已经存在了else if (ret == 2){//增加一行数据LogHelper.WriteLogInfo("数据库文件已存在,增加一行数据");if (myAccess.AddTestData(strSN, strResult, strTime)){LogHelper.WriteLogInfo("增加一行数据成功");return true;}//增加数据失败else{LogHelper.WriteLogInfo("增加一行数据失败");return false;}}//access 文件创建失败else{LogHelper.WriteLogInfo("access文件创建失败");return false;}}catch (Exception ex){LogHelper.WriteLogInfo("异常-->" + ex.Message);throw;}}}
日志log4net 参考
log4net(一)将log4net封装在类库项目中_log4net 封装-CSDN博客
在dll类库项目中:
1、下载包:添加log4net.dll的引用
2、添加配置文件并命名为:log4net.config。设置复制到输出目录:始终复制
<?xml version="1.0" encoding="utf-8"?> <configuration><configSections><section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/></configSections><!--(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低)--><log4net><!--正常日志类--><logger name="info"><level value="ALL" /><appender-ref ref="InfoAppender" /></logger><!--错误日志类--><logger name="error"><level value="ALL" /><appender-ref ref="ErrorAppender" /></logger><!--正常日志附加介质--><appender name="InfoAppender" type="log4net.Appender.RollingFileAppender"><!--日志路径--><param name= "File" value= "MESLog\"/><!--是否是向文件中追加日志--><param name= "AppendToFile" value= "true"/><!--log保留天数--><param name= "MaxSizeRollBackups" value= "100"/><!--写到一个文件--><staticLogFileName value="false"/><!--单个文件大小。单位:KB|MB|GB--><maximumFileSize value="200MB"/><!--最多保留的文件数,设为"-1"则不限--><maxSizeRollBackups value="-1"/><!--日志文件名格式--><param name= "DatePattern" value= "yyyyMM\\yyyyMMdd'_Info.log'"/><!--日志根据日期滚动--><param name= "RollingStyle" value= "Date"/><!--日志文本格式--><layout type="log4net.Layout.PatternLayout"><!--%d 时间,等价于 date--><!--%t 线程--><!--%-5p 日志级别--><!--%C 出错类,等价于 class,可以使用:%class{1},如果给出了精度说明符,则只会打印类名中最右边的组件的相应数量。默认情况下,类名以完全限定形式输出。--><!--%L 出错行--><!--%M 方法名,等价于 method--><!--%m 日志信息,等价于 message--><!--%n 换行--><param name="ConversionPattern" value="******************************%d 线程[%t] 日志级别[%p] ******************************%n类名:%class{1}%n方法名:%M - 第 [%L] 行%n消息:%m%n%n" /></layout></appender><!--错误日志附加介质--><appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender"><!--日志路径--><param name= "File" value= "MESLog\"/><!--是否是向文件中追加日志--><param name= "AppendToFile" value= "true"/><!--log保留天数--><param name= "MaxSizeRollBackups" value= "100"/><!--日志文件名是否是固定不变的--><param name= "StaticLogFileName" value= "false"/><!--日志文件名格式--><param name= "DatePattern" value= "yyyyMM\\yyyyMMdd'_Error.log'"/><!--日志根据日期滚动--><param name= "RollingStyle" value= "Date"/><param name="MaxFileSize" value="1"/><!--日志文本格式--><layout type="log4net.Layout.PatternLayout"><!--%d 时间,等价于 date--><!--%t 线程--><!--%-5p 日志级别--><!--%C 出错类,等价于 class,可以使用:%class{1},如果给出了精度说明符,则只会打印类名中最右边的组件的相应数量。默认情况下,类名以完全限定形式输出。--><!--%L 出错行--><!--%M 方法名,等价于 method--><!--%m 日志信息,等价于 message--><!--%n 换行--><param name="ConversionPattern" value="******************************%d 线程[%t] 日志级别[%p] ******************************%n类名:%class{1}%n方法名:%M - 第 [%L] 行%n消息:%m%n%n" /></layout></appender></log4net> </configuration>
3、在AssemblyInfo.cs文件里,写入代码,这样就和项目工程建立起联系
//增加日志配置 [assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
4、封装一个类:LogHelper
注意:e=null不能直接写入,否则会异常
/// <summary>/// 日志类/// </summary>public class LogHelper{private static ILog logInfo = LogManager.GetLogger("info");private static ILog logError = LogManager.GetLogger("error");/// <summary>/// 打印正常日志/// </summary>/// <param name="message"></param>/// <param name="e"></param>public static void WriteLogInfo(object message, Exception e = null){if (e == null){logInfo.Info(message);}else{logInfo.Info(message, e);}}/// <summary>/// 打印错误日志/// </summary>/// <param name="message"></param>/// <param name="e"></param>public static void WriteLogError(object message, Exception e = null){if (e == null){logError.Error(message);}else{logError.Error(message, e);}}}
5、主程序调用:(我这个是以接口的形式访问,可以写在控制台里)
LogHelper.WriteLogInfo(strTemp); LogHelper.WriteLogError(ex.Message);
写的日志截图
方法名中带出的行数,需要.pdb文件才能正确写出来,如果没有.pdb文件则写的行数是0
VS2015使用Costura.Fody将dll打包到exe_fody 打包 dll-CSDN博客
一、Costura.Fody是什么?
Costura.Fody是一个Fody框架下的插件,可通过Nuget安装到VS工程中。
安装之后,就可以将项目所依赖的DLL(甚至PDB)文件全部打包到EXE文件里。
我的vs版本是2017,对应的这个2个版本正好,如果安装其他版本编译的时候就出错了
4.修改FodyWeavers.xml
修改FodyWeavers.xml内容为如下:
<?xml version="1.0" encoding="utf-8"?> <Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"><Costura /> </Weavers>
重新编译即完成了