您可以使用实体框架 4.1 代码优先方法创建 sql 视图/存储过程吗
Entity Framework 4.1 Code First 非常适合创建表和关系。是否可以使用代码优先方法创建 sql 视图或存储过程?任何有关此的指示都将受到高度赞赏。多谢!
Entity Framework 4.1 Code First works great creating tables and relationships. Is it possible to create sql views or stored procedure using Code first approach? Any pointers regarding this will be highly appreciated. Thanks a lot!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我们在实体框架代码优先迁移中支持存储过程。我们的方法是创建一些文件夹来保存 .sql 文件(例如 ~/Sql/)。在该文件夹中创建 .sql 文件以用于创建和删除存储过程。例如
Create_sp_DoSomething.sql
和Drop_sp_DoSomething
。由于 SQL 是以批处理方式运行,并且CREATE PROCEDURE..
必须是批处理中的第一个语句,因此请将CREATE PROCEDURE...
作为文件中的第一个语句。另外,请勿将GO
放在DROP...
之后。如果您还没有资源文件,请将资源文件添加到您的项目中。将 .sql 文件从解决方案资源管理器拖到资源设计器的文件视图中。现在创建一个空迁移(Add-Migration SomethingMeaningful_sp_DoSomething
)并使用:~/Sql/Create_sp_DoSomething.sql
~/Sql/Drop_sp_DoSomething.sql
We support stored procedures in our Entity Framework Code First Migrations. Our approach is to create some folder to hold the .sql files (~/Sql/ for example). Create .sql files in the folder for both creating and dropping the stored procedure. E.g.
Create_sp_DoSomething.sql
andDrop_sp_DoSomething
. Because the SQL runs in a batch andCREATE PROCEDURE..
must be the first statement in a batch, make theCREATE PROCEDURE...
the first statement in the file. Also, don't putGO
after theDROP...
. Add a resources file to your project, if you don't have one already. Drag the .sql files from solution explorer into the Files view of the Resources designer. Now create an empty migration (Add-Migration SomethingMeaningful_sp_DoSomething
) and use:~/Sql/Create_sp_DoSomething.sql
~/Sql/Drop_sp_DoSomething.sql
乍一看,我真的很喜欢 Carl G 的方法,但它涉及大量的手动交互。在我的场景中,我总是删除所有存储过程、视图……并在数据库发生更改时重新创建它们。这样我们就可以确保一切都是最新的最新版本。
通过设置以下初始化程序来进行重新创建:
然后,只要有迁移准备就绪,我们的种子方法就会被调用。
SQL 语句存储在 *.sql 文件中,以便于编辑。确保您的文件将“构建操作”设置为“内容”,并将“复制到输出目录”设置为“始终复制”。我们查找文件夹并执行其中的所有脚本。不要忘记在 SQL 中排除“GO”语句,因为它们无法使用 ExecuteSqlCommand() 执行。
我当前的目录布局如下:
现在您只需将额外的存储过程放入文件夹中,所有内容都会得到适当更新。
At first sight I really like the approach of Carl G but it involves a lot of manual interaction. In my scenario, I always drop all stored procedures, views... and recreate them whenever there is a change in the database. This way we are sure everything is up-to-date with the latest version.
Recreation happens by setting the following Initializer:
Then our seed method will get called whenever there is a migration ready
SQL Statements are stored in *.sql files for easy editing. Make sure your files have "Build Action" set to "Content" and "Copy to Output Directory" set to "Copy Always". We lookup the folders and execute all scripts inside. Don't forget to exclude "GO" statements in your SQL because they cannot be executed with ExecuteSqlCommand().
My current directory layout is as follows:
Now you just need to drop extra stored procedures in the folder and everything will get updated appropriately.
要扩展 bbodenmiller 的答案,在 Entity Framework 6 中,DbMigration 类 具有诸如 AlterStoredProcedure 之类的方法,这些方法允许修改存储过程,而不必一直下降到原始 SQL。
下面是
Up()
迁移方法的示例,该方法更改名为 EditItem 的现有 SQL Server 存储过程,该过程采用三个类型为int
、nvarchar(50)< 的参数。分别是 /code> 和
smallmoney
:在我的计算机上,此迁移脚本生成以下 SQL:
To expand on bbodenmiller's answer, In Entity Framework 6, the DbMigration class has methods such as AlterStoredProcedure which allow for modification of stored procedures without having to drop all the way down to raw SQL.
Here's an example of an
Up()
migration method which alters an existing SQL Server stored procedure named EditItem which takes three parameters of typeint
,nvarchar(50)
, andsmallmoney
, respectively:On my machine, this migration script produces the following SQL:
EF 代码优先方法期望数据库中没有逻辑。这意味着没有存储过程,也没有数据库视图。因为代码优先方法不提供任何机制来自动为您生成此类构造。如果这意味着生成逻辑,它怎么能做到这一点呢?
您必须通过手动执行在自定义数据库初始值设定项中自行创建它们创建脚本。我不认为这种自定义 SQL 构造可以通过 SQL 迁移来处理。
EF code-first approach expects that there is no logic in the database. That means no stored procedures and no database views. Because of that code-first approach doesn't provide any mechanism to generate such constructs automatically for you. How could it do that if it means generating logic?
You must create them yourselves in custom database initializer by manual executing creation scripts. I don't think that this custom SQL constructs can be handled by SQL migrations.
似乎记录很少,但是您现在可以使用 AlterStoredProcedure, CreateStoredProcedure, DropStoredProcedure, MoveStoredProcedure, 实体框架 6 中的RenameStoredProcedure我还没有尝试过,所以还不能给出如何使用它们的例子。
It appears to be poorly documented however it appears you can now do some Stored Procedure manipulation using AlterStoredProcedure, CreateStoredProcedure, DropStoredProcedure, MoveStoredProcedure, RenameStoredProcedure in Entity Framework 6. I haven't tried them yet so can't yet give an example of how to use them.
emp 的设计就像冠军一样!我正在使用他的模式,但我还在 DbContext 类中映射存储过程,该类允许简单地调用这些上下文方法,而不是使用 SqlQuery() 并直接从我的存储库调用过程。由于随着应用程序的增长,事情可能会变得有点棘手,因此我在 Seed 方法中创建了一个检查,以确保实际的存储过程参数计数与映射方法上的参数计数相匹配。我还更新了提到的 DROP 循环 emp。我不必为 drop 语句维护单独的文件夹/文件,只需读取每个 sql 文件的第一行并将
CREATE
替换为DROP
(只需确保第一个行始终只是CREATE PROCEDURE ProcName
)。这样,每次运行 Update-Database 时,StoredProcs 文件夹中的所有过程都会被删除并重新创建。该 drop 也包含在 try-catch 块中,以防过程是新的。为了使过程参数计数起作用,您需要确保在 tsql 周围包裹一个BEGIN/END
块,因为文件的每一行都会被读取到 BEGIN。还要确保每个 sp 参数都位于新行。享受!
emp's design works like a champion! I'm using his pattern but I also map stored procedures inside of my DbContext class which allows simply calling those context methods instead of using SqlQuery() and calling the procedures directly from my repository. As things can get a bit hairy when the application grows, I've created a check within my Seed method that makes sure the actual stored procedure parameter count match up to the parameter count on the mapping method. I've also updated the DROP loop emp mentioned. Instead of having to maintain a separate folder/file for the drop statements, I simply read the first line of each sql file and replace
CREATE
withDROP
(just make sure the first line is always justCREATE PROCEDURE ProcName
). This way all procedures in my StoredProcs folder get dropped and recreated each time Update-Database is ran. The drop is also wrapped in a try-catch block in case the procedure is new. For the procedure parameter count to work, you'll need to make sure you wrap aBEGIN/END
block around your tsql since each line of the file is read up to BEGIN. Also make sure each sp parameter is on new line.Enjoy!
正如 Ladislav 指出的那样,
DbContext
通常确实倾向于最小化数据库中的逻辑,但可以通过使用context.Database.ExecuteSqlCommand()
或context.Database.SqlQuery()
。As Ladislav pointed out,
DbContext
in general does tend to minimize the logic in the database, but it is possible to execute custom SQL by usingcontext.Database.ExecuteSqlCommand()
orcontext.Database.SqlQuery()
.