需求:每隔一段时间存一条数据到Access数据库,数据库文件以日期命名,把这个功能封装以供调用
分解任务:1新建数据库文件 2新建数据库表 3向数据库表中增加数据 4需要有日志记录执行结果 5由于过多的dll不易于传播维护,需要将这些dll封装
参考资料:
关闭ADOX.Catalog创建Access的链接,避免ldb锁定-CSDN博客
我们在动态创建ACCESS数据库的时候,往往知道如何去创建,但是对于创建后的销毁资源做的不太好,会出现.ldb锁定文件。有时候会影响到我们对数据库的操作。 首先加两个COM组件引用: 1) Microsoft ActiveX Data Objects 2.8 Library 2) Microsoft ADO Ext. 2.8 for DDL and Security 创建数据库: ADOX. CatalogClass catalog = new ADOX. CatalogClass(); string str = "Provider=Microsoft.Jet.OleDB.4.0"; str += ";Data Source="+ file; // Your *.mdb File,注意扩展名必须为mdb,否则不能插入表 str += ";Jet OLEDB:Engine Type=5"; str += ";Locale Identifier=0x0804"; // Locale Identifier=0x0804,支持简体中文 catalog.Create(str); // 关闭数据库: ADODB. Connection connection = catalog.ActiveConnection as ADODB. Connection; if (connection != null) { connection.Close(); } catalog.ActiveConnection = null; catalog = null; 这样关闭后,你就可以修改数据库扩展名或者执行删除等操作。 当创建ACCESS数据库的时候,会自动创建一个连接,为了释放.ldb文件,必须关闭这一连接。而这个连接是ADODB类的,所以很多人一直都找不到释放连接的方法。 谢谢转载引用本文! 转载时如有可能请保留以下链接, 作者将表示感谢! 原文地址:http://www.bmpj.net/forum-redirect-tid-455-goto-lastpost.html
创建文件 创建表 插入一条数据即为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>
重新编译即完成了
标签:LogHelper,string,c#,创建,catalog,Access,ADOX,new,null From: https://www.cnblogs.com/ckrgd/p/18599542