F#类型提供程序和持续集成,第2部分

9
这是我之前关于F#类型提供程序和持续集成的跟进问题(实际上是几个问题)。
在以特性分支为驱动的开发中,使用SqlDataConnection类型提供程序作为编译时检查代码/数据库完整性的好主意;假设构建数据库也是您CI流程的一部分,那么每次提交/构建时,您都会知道没有对代码进行更改而未应用于数据库的情况。
然而,还有几个问题:
  1. The name (as well as the location) of the config file is not the same at compile time as at runtime, e.g. app.config -> MyApp.exe.config, which will result in a runtime error if you try to use

    SqlDataConnection<ConnectionStringName="DbConnection", ConfigFile="app.config">
    

    (Actually, specifying ConfigFile="app.config" is not necessary, since it is the default value.)

    The runtime error can be avoided by copying the app.config file to the output directory (there’s a setting for that), but that would result in having both an app.config and a MyApp.exe.config file in the output directory. Not very pretty. Adding a separate configuration file for type providers would be another solution, but imho that’s not very pretty either.

    Question: Has anyone come up with a more elegant solution to this problem?

  2. The next problem arises when you come to the build server. It is most likely that you don’t want to compile against the same database as you did while developing, thus requiring a different connection string. And yes, in production you’d need yet another one.

    Question: How do you go about solving this in the most convenient way? Remember, the solution has to be a working part of a CI process!

  3. This strategy would require generating the database on each build at the build server, probably from a baseline script with some feature/sprint update scripts.

    Question: Has anyone tried this and how did it affect build times? If yes, how did you create this step?


我找到了一个相关的问题: https://dev59.com/DGYr5IYBdhLWcg3wVYsg但是这个问题仍然没有得到解答。这是否意味着没有人在实际生产代码中使用SqlDataConnection?=O - spacedoom
我目前正在使用SqlEntityConnection,但这并没有真正改变什么。我已经开始通过在TeamCity中进行一些魔法来实现解决方案,但我仍然对听到您的解决方案感兴趣。 - spacedoom
如果您有解决方案,最好将其作为答案发布,而不是作为问题的更新。 - John Palmer
@JohnPalmer 感谢您的建议。我收到了一条消息,大概意思是“最好编辑您的问题”,但是在再次阅读消息后,我遵循了您的建议。 - spacedoom
2个回答

2

我一开始有些不愿意接受@Gustavo的回复,但经过认真思考后,我决定接受。请查看我的答案以获取更多细节。 - spacedoom

0

我熟悉@Gustavo提出的解决方案,但我一直觉得有些可疑。需要两次指定连接字符串...然而,当我再次得到同样的回复时,我慢慢意识到答案一定是正确的,而且是我想错了。这是我的结论:

回复中指出您可以使用接受连接字符串的GetDataContext重载。如果将其更改为“应该”,至少对我来说,事情就变得更清晰了。

问题在于,我一直将类定义视为编译时指令和运行时变量,尽管这是可能的,但这并不是一个好主意。ConfigFile参数的默认值如我们已经看到的是“app.config”,但是该文件在运行时不存在(以该名称),因此尝试使用它是没有意义的,因此只剩下GetDataContext作为唯一合理的选项。我建议您这样做:

  1. 将编译时设置保存在名为compilation.config(或您喜欢的其他名称)的文件中,并在类定义中指定该文件以供使用。

  2. 使用接受连接字符串的GetDataContext重载进行运行时解析,并在app.config文件中指定此连接字符串。

最终,您将得到类似于以下内容的东西:

type private dbSchema = SqlEntityConnection<ConnectionStringName="DbConnection", ConfigFile="compilation.config">
let private db = dbSchema.GetDataContext(ConfigurationManager.ConnectionStrings.["DbConnection"].ConnectionString)

哇,这甚至支持SRP;一个文件中的编译时设置和另一个文件中的运行时设置!

关于我的其他问题,我认为答案在持续部署管道中的某些脚本中。不过,我仍然对其他解决方案感兴趣。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接