使用实体框架在数据库上执行命令

Posted

技术标签:

【中文标题】使用实体框架在数据库上执行命令【英文标题】:Using Entity Framework to execute commands on a database 【发布时间】:2017-06-12 01:44:20 【问题描述】:

我想根据我数据库中的其他数据对我的数据库进行可能非常大的插入。性能对这个应用程序很重要,即使使用 SqlBulkCopy 也会让这个过程减慢一点,我不喜欢。

所以问题是:是否可以使用 Linq to EF 自动生成并在数据库上运行 SQL 代码,而不向用户返回任何内容?对我来说这似乎是可能的,我只是不知道如何绕过它。

这里的前提是:像下面这样的东西可以工作吗?

myContext.OutputTable.AddRange(
    myContext.TableA.Join(
        myContext.TableB,
        a => a.myAKey,
        b => b.myBKey,
        (a, b) => new  a.fieldA, a.fieldB, b.fieldC ).Select(
    output => new OutputTable
    
        myOutputColumnA = output.FieldA,
        myOutputColumnB = output.FieldB,
        myOutputColumnC = output.FieldC
    )
);

也许我在这里尝试做的事情并不明显。我基本上是在尝试使用 TableA 和 TableB 中的数据将数据插入“OutputTable”,而不让 EntityFramework 将数据返回给应用程序。现在,我知道可以使用ExecuteNonQuery() 来运行这种插入语句,但最终,出于几个不同的原因,我不想这样做:我希望在 C# 中维护整个代码;我还想保留 Linq 提供的调试功能(因为我使用 Visual Studio,所以在代码失败的地方出现查询失败是有帮助的)。

我知道 Linq to EF 生成在数据库上执行的 SQL,所以我似乎可以做到这一点(可能必须故意忽略延迟加载,因此代码实际执行)。上面的代码不执行,我相信在不能以这种方式在Select() 语句中实例化新对象的前提下(Linq to EF 不知道如何处理它)。那么最终,这是一条可行的道路吗?如果不是,是否有任何可行的替代方案?

【问题讨论】:

你在说多少数据?数百?数千?百万? @Fran 实际上,在数万到数百万之间。它第一次运行可能是数千万,虽然我不希望它定期那么大。 只能通过编写存储过程来实现。不要指望任何安全的 .Net 应用程序能够操作它不拥有自己的数据(即内存内容)。无论如何,“实体框架”和“快速”是最终的矛盾。 @GertArnold 我曾考虑使用存储过程,但我不喜欢分离代码库,只是为了可维护性。如果这是不可避免的,那么我会这样做(从我所见,这可能是最好的选择),因为我最终更关心性能而不是这个特定部分的可维护性。 【参考方案1】:

使用 EF 不会比 SqlBulkCopy 更快。 EntityFramework 是一个 ORM,因此即使您关闭所有可能的选项,它仍然会比 SqlBulkCopy 慢,因为它想要获取原始 sql 数据并物化对象。

SqlBulkCopy 就像打开一个通往数据库的水管。它将关闭约束并使用定期写入数据库的不同机制。

任何比这更快的都必须包含在数据库中,就像提到的 Gert 的评论一样。

这里有一个旧的但很好的 SqlBulkCopy 解释

http://www.sqlbi.com/wp-content/uploads/SqlBulkCopy-Performance-1.0.pdf

【讨论】:

以上是关于使用实体框架在数据库上执行命令的主要内容,如果未能解决你的问题,请参考以下文章

实体框架不遵守命令超时

执行命令定义时发生错误。有关详细信息,请参阅内部异常 (linq)

Java的SpringMVC框架操作数据库,一定要建立对应的实体类吗,能不能通过直接嵌入sql命令方式操作数据库?

在不使用其他项目的情况下添加实体框架核心迁移

如何使用实体框架向数据库服务器询问当前日期时间?

IDENTITY_INSERT ON不被实体框架DBSet.Add方法所尊重