问题:我们希望对一些csv数据执行一些ETL(提取,转换,加载),其中该过程通过ASP.NET网站中的网页手动启动。
上下文
我们有一个ASP.NET网站,其中包含受限制的Admin
部分。
在本节中,我们希望添加一个页面,允许用户单击按钮选择要导入Sql Server数据库表的文件。
其中一些文件可能包含很多行--500,000。 (每行大约300-400个字符,超过大约13个'列'.. csv'd。)。
现在,导入此内容可能需要一段时间。就像,我希望将文件内容上传到某个地方然后开始一些后台任务。
我想知道人们现在是怎么做的?
我们在Azure上,所以我猜我们可以访问Azure blob和队列以及webjobs。只是不确定这是否是一个已经解决了大量时间的常见问题,并且有一些参考资料可供审查。
谢谢!
答案 0 :(得分:1)
很容易。我之前遇到过这个问题。
很长的路:
1._上传文件。
2._拿文件做验证
3._转换为数据表(我真的不记得我使用过的库的名称)
4._使用sql的本地批量(没有ORMS,它非常简单快速)
注意:确保将webconfig配置为支持繁重的文件。
简短的方法: 使用SSRS创建一个包含csv的包并将字段映射到表
答案 1 :(得分:1)
我将假设你已经找到了CSV解析(使用CSV Helper或类似工具)。但是你遇到麻烦的部分是如何在一个网站中处理这个长时间运行的任务,当正常的页面交互在请求/响应生命周期中运行时。但解析一个大的CSV文件对于正常的请求/响应生命周期来说太长了。
是的,这是一个已解决的问题。您可以在Azure上使用相当多的工具,您已经提到过其中的一些工具。您也可以启动外部应用程序来执行处理,可能使用消息队列。但您也可以完全在ASP.NET中完成。 Scott Hanselman对此问题有一个great blog post。它归结为使用某种类型的库来设计,以便在没有HTTP上下文的情况下安全地处理在ASP.NET中运行的危险,并且通常选择一种可以在应用程序崩溃中幸存的工具。像Quartz.NET和Hangfire这样的库。
基本上,通过这些类型的库,您可以完成一项工作来完成处理,并且可以在以后完成后再查看。
答案 2 :(得分:0)
在SSIS等单一工具中执行所有ETL流程。稍后处理您的自定义ETL工具将是一场噩梦。或者您的网站可以触发SSIS ETL。让您的网站将文件放在SSIS可以获取的位置。
答案 3 :(得分:0)
如果您不想使用SSIS,但使用的是EF,则可以使用CsvHelper。要通过EF加快导入,请将AutoDetectChangesEnabled
设置为false
以获取用于导入的dbContext。我已经使用了这个,虽然我的数据包含不到10万条记录,并且在5到20列之间变化,但我的导入运行时间非常短暂。
我写了CsvHelperWrapper,其中有一个ImportHandler
类。此类有一个ImportAsync
方法,它接受文件路径和其他参数,并在调用CsvHelper之前执行某些EF函数。但在您的情况下,您将使用流阅读器替换文件路径。
我在windows服务中使用了我的ImportHandler,它还定义了一个自定义配置部分,我可以为需要导入的每个文件定义需要传递给ImportHandler的所有细节(例如,从哪里获取csv文件,什么文件名模式映射到哪个实体类,它应该假设csv文件有标题行,它是否应该从csv修剪数据等。)但是你可以询问你的用户那些细节,然后在后台运行导入。
使用这种方法,对于我需要处理的每个新导入文件,我只需编写实体类来接收它,如果后端表尚不存在,EF将为我创建它。如果您希望验证与数据库中其他数据相关的导入数据,您可以编写并在导入后调用它。