C#中对web程序进行数据库连接配置的问题,有没有winform和webforom通用的办法?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#中对web程序进行数据库连接配置的问题,有没有winform和webforom通用的办法?相关的知识,希望对你有一定的参考价值。

我以前只是用C#来做winform程序,之前的做法是写了个类库(mData.dll)来专门做数据库中每一个表的增加、删除、修改、查询、统计、筛选等操作。然后写另一个类库(mBLL.dll)专门专门针对不同的窗体上所有关于需要访问数据库的操作。主项目中只是写窗体效果、输入验证、控制等之类的东西。这个办法我在以前做信息管理系统时一直这样用。这段时间我需要做一个webform和系统。之前没有做过,但因为都是C#也有很多相通之处,就把以前的mData.dll,和mBLL.dll两个类库直接拿来用了。因为只是系统从winform改成webform,业务和操作是不变的。

我的引用关系是主项目myAPP.exe引用了mBLL.dll,mBLL.dll引用了mData.dll。也就是说在主项目看来,根本就不知道mData.dll的存在。这在winform程序里应用的很好。

但是系统要改成webform时问题来了,我为了消除一些访问数据库时的麻烦的实例化过程,我在mData.dll里面对原有的C#的ADO.net的东西进行了封装。配了一个conn.xml,在这里面写上数据库的连接字符串。只要我在mBLL.dll里调用mData.dll里的类,实例化,就会自动把连接数据库的工作做好,我直接写SQL语句或存储过程名就可以了。在主项目里每一个操作只是对mBLL.dll里的某一个类的某一个函数的调度。并不涉及到数据库连接什么的。但是WebForm里需要把数据库连接设计在web.config里,这个文件只是主项目里存在。我的mData.dll根本就不知道web.config的存在,但不用说去调用它了。这样一来,我的数据库连接过程就无法完成。为了完成这一过程,我在主项目里每一次要操作,就要去把数据库连接字符串一层层传下去。实在太麻烦了。请问大家是怎么处理这个问题的?

不知道我说清了没有。如果我的mData.dll不用web.config里的配置,还使用conn.xml,这样一来另一个问题出现了,这个xml文件里存放的是一个access的数据库,路径是相对的,那么在webform项目中,不同目录下的页面在执行时,会产生不同的当前目录,相对路径就会出错,为了不出错,就要在每一个目录下放一个conn.xml,然后把里面的相对路径配合着做一些改动,这也太让人不能接受了。

我不知道我说清我的问题了没有,请问大家是怎么处理这一问题 的?

参考技术A 有!你可以选择使用虚拟路径解决这个问题!很简单的,要想两个通用,就把数据库连接字符串写在一个可知的文件里,到时候去读取就行了 参考技术B 不知道我说清了没有。如果我的mData.dll不用web.config里的配置,还使用conn.xml,这样一来另一个问题出现了,这个xml文件里存放的是一个access的数据库,路径是相对的,那么在webform项目中,不同目录下的页面在执行时,会产生不同的当前目录,相对路径就会出错,为了不出错,就要在每一个目录下放一个conn.xml,然后把里面的相对路径配合着做一些改动,这也太让人不能接受了

针对你这个问题,对于路径的话,/conn.xml代表你整个网站的根目录下的conn.xml文件。本回答被提问者和网友采纳
参考技术C 重写一个配置文件(ini结尾),记事本编辑
[connstr]
connstr=Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Database1.mdb;Persist Security Info=False

这是win32 api
[DllImport("kernel32")]//读取ini win32 api
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);

这是访问方法
public string ReadValue(string section, string key)

StringBuilder temp = new StringBuilder(255);// 每次从ini中读取多少字节
string path = Directory.GetCurrentDirectory() + "\\config.ini";//必须是绝对路径
// section=配置节,key=键名,temp=上面,path=路径
GetPrivateProfileString(section, key, "读取错误", temp, 255, path);
return temp.ToString(); //注意类型的转换


string aa =ReadValue("connstr","connstr")
aa就是那个连接字符串了
参考技术D 没听清楚

如何在c#中对所有日志进行分组

【中文标题】如何在c#中对所有日志进行分组【英文标题】:How to group all the logs in c# 【发布时间】:2021-10-18 04:24:01 【问题描述】:

我有一个主 mvc 应用程序,它将调用 3 个 Web api 应用程序,并将使用 log.LogInformation() 为每个方法命中和 mvc 项目中的每个控制器写入日志。我创建了一个名为 username 的变量,并让每个日志都在消息末尾包含该用户名。 IE。 log.LogInformation("You have hit the home page of the mvc project... @Username, username)so 在我使用@Username 并传递username 的每条日志消息的末尾。我想根据该变量 username 对所有整个日志进行分组。有没有办法将记录到记录器的所有整个日志分组,从 mvc 项目到每个调用的 web api 项目?我正在使用Serilog 编写日志。


跟进:

因此,在阅读 Log scopes 并使用 BeginScope 之后,我可以在我的最后一个控制器中的 mvc 项目中创建另一个方法,如下所示:

    public IActionResult GetAllLogs()
    
        using (_logger.BeginScope("Gathering all the logs created for @Username", HomeController.username))
        

        
    

所以保留它可以从 mvc 项目中收集所有日志,包括 web api 项目日志?我不需要在using() 语句中做任何事情?

【问题讨论】:

您可以检查Log scopes (Read here)。使用BeginScope,范围内的所有日志语句都将属性记录为自定义属性。 因此,使用 Log 范围,您无需将属性传递到第 n 个函数级别。由于属性被记录为自定义属性,因此您可以进行分组、过滤等。 谢谢!我正在阅读Log scopesBeginScope 我不需要在using() 语句中执行任何操作来收集所有日志,因为BeginScope 将收集所有日志?请查看我编辑的帖子@user1672994 我也看到了这个docs.microsoft.com/en-us/dotnet/api/…,但它传递了一个属性......你是说我不需要?它怎么知道我想使用变量username @MarrkCo - 我已经发布了答案,如果您需要任何详细信息,请查看并告诉我。 【参考方案1】:

您可以检查日志范围 (Read here)。使用 BeginScope,范围内的所有日志语句都会将属性记录为自定义属性。

例如:Scope 在调用 Method1 -> Method2 -> Method3DoesTheLogging 的 SomeAPI API 处启动。现在直到方法Method3DoesTheLogging,不需要传递任何属性来记录日志语句。日志框架会自动附加在BeginScope.中定义的自定义属性

    public IActionResult SomeAPI()
    
        using (_logger.BeginScope("Gathering all the logs created for @Username", HomeController.username))
        
            Method1();
        
    
    
    public void Method1()
    
        Method2();
    
    
    public void Method2()
    
        Method3DoesTheLogging();
    
    
    public void Method3DoesTheLogging()
    
        _logger.LogInformation("This log statement will log the username automatically as custom property".);
    

因此,使用 Log 范围,您无需将属性传递到第 n 个函数级别。由于属性被记录为自定义属性,因此您可以进行分组、过滤等,

【讨论】:

感谢您的详细解释。那么无论.BeginScope() 放置在哪里,它就会开始根据自定义属性收集/分组所有日志?如果您不知道在应用程序启动期间将调用哪个方法怎么办?因为我看到您调用了发生日志记录的最后一个方法?而且我的每个方法都有一个日志,所以当我在一个方法中调用一个方法时,我仍然不需要传递属性吗? when I would call a method within a method, I still would not need to pass the property - 是的,不需要。开始范围定义自定义属性的范围,该范围将由作为范围一部分的日志语句记录。 What if you do not know which method will be called during the start of the application- 这个概念称为结构日志记录,其中每个方法定义要记录的内容;其他自定义属性是根据它们所在的范围记录的。所以假设如果从两个地方调用 method1,1) 有范围,2) 没有范围。然后对于#1,将为#2 记录自定义属性,不会记录自定义属性....所以从调用链的函数开始是一个很好的实践。 使用 Scope 的另一个优点是还可以使用 Scope 的嵌套。您可以尝试在this repo 中创建的示例。 我现在关注,谢谢你给我解释! :)

以上是关于C#中对web程序进行数据库连接配置的问题,有没有winform和webforom通用的办法?的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中对“不可测试”的应用程序进行自动化测试。单元/集成/功能/系统测试 - 如何?

如何在没有登录的角度应用程序中对 Web Api 进行身份验证

从Web.Config获取多个connectionStrings到字典c#没有循环

跟踪在 C# 应用程序或 SQL Server 中对 SQL Server 进行更改的人员

如何在 C# 中对二维(矩形)数组进行排序?

避免在 c# 中对一段代码进行调试和调用堆栈