How to Create Custom Stored Procedures Using Code First Fluent API - entity-framework

There are many articles that show how to create Insert, Update, Delete procedures using Code First like this one.
How about custom procedure like this simple select statement:
Select * from Customers
I could make changes to the Up and Down Migration methods, but is there a way to create custom procs using Fluent API directly.

Here is a solution which I don't recommand but If you want to use DbContext.Database, here it is:
using(var db = new MyDbContext(connectionString))
{
db.Database.ExecuteSqlCommand("CREATE PROCEDURE MyProcedure ... END;");
var command = "EXEC MyProcedure;";
IEnumerable<Customer> customers = db.Database.SqlQuery<Customer>(command, null);
}

Related

How to select data from old database and insert it into new one within doctrine migration?

I use 'doctrine/DoctrineORMModule' module for zend framework 3 (MVC). I have configured 'orm_default' and can configure 'orm_old' but don't know how to use 'orm_old' within migration file.
I can do this within migration file:
public function up(Schema $schema) : void
{
$sql = "INSERT INTO `some_table` VALUES ('some_value','','',NULL,NULL,'1');";
$this->addSql($sql);
//...
But in general I need run something like this:
INSERT INTO DB2.T2(id, title, description)
SELECT id, title, description FROM DB1.T1;
How to do that?
If I understand correctly, you'd like to use Doctrine Migrations for two database connections: orm_default and orm_old.
This is possible in Doctrine, but not with the Zend Framework DoctrineORMModule. This is mentioned very shortly in the official documentation: https://github.com/doctrine/DoctrineORMModule/blob/master/docs/migrations.rst#multiple-migration-configurations
The best thing you can do is to use two separate cli-config files with the same database connections, and put the migrations in two seperate folders. You can then use the 'default' doctrine CLI tools (vendor/bin/doctrine migrations:migrate ) to run migrations for the two connections.
Adding this functionality to the DoctrineORMModule was requested, but never implemented. You can read more about it right here:
https://github.com/doctrine/DoctrineORMModule/issues/537

EF Core Bulk Delete on PostgreSQL

I’m trying to do a, potentially, large scale delete operation on a single table. (think 100,000 rows on a 1m row table)
I’m using PostgreSQL and EntityFrameworkCore.
Details: The application code has a predicate to match and knows nothing about how many rows potentially match the predicate. It could be 0 row/s or a very large amount.
Research indicates EF Core is incapable of handling this efficiently. (i.e. the following code produces a Delete statement for each row!)
Using (var db = new DbContext)
var queryable = db.Table.AsQueryable()
.Where(o => o.ForeignKey == fKey)
.Where(o => o.OtherColumn == false);
db.Table.RemoveRange(queryable);
await db.SaveChangesAsync();
So here is the SQL I would prefer to run in a sort of batched operation:
delete from Table
where ForeignKey = 1234
and OtherColumn = false
and PK in (
select PK
from Table
where ForeignKey = 1234
and OtherColumn = false
limit 500
)
There are extension libraries out there, but I’ve yet to find an active one that supports Postgres. I’m currently executing the raw sql above through EF Core.
This leads to a couple questions:
Is there anyway to get EF Core to delete these rows more efficiently on Postgres using LINQ, etc?
(Seems to me like handing the context a queryable should give it everything it needs to make the proper decision here)
If not, what are your opinions on deleting in batches vs handing the DB just the predicate?
I think you are trying to do something you should not use EntityFrameworkCore for. The object of EntityFrameworkCore is to have a nice way to move data between a .Net-Core application and a database. The typical useway is single or a small amount of objects. For bulk operations there are some nuget-packages. There is this package for inserting and updating with postgres.This article by the creator explains how it uses temporary tables and the postgres COPY command to do bulk operations. This shows us a way to delete rows in bulk by id:
var toDelete = GetIdsToDelete();
using (var conn = new NpgsqlConnection(connectionString))
{
conn.Open();
using ( var cmd = conn.CreateCommand())
{
cmd.CommandText =("CREATE TEMP TABLE temp_ids_to_delete (id int NOT NULL) ON COMMIT DROP ");
cmd.Prepare();
cmd.ExecuteNonQuery();
}
using (var writer = conn.BeginBinaryImport($"COPY temp_ids_to_delete (id) FROM STDIN (FORMAT BINARY)"))
{
foreach (var id in toDelete)
{
writer .StartRow();
writer .Write(id);
}
writer .Complete();
}
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "delete from myTable where id in(select id from temp_ids_to_delete)";
cmd.Prepare();
cmd.ExecuteNonQuery();
}
conn.Close();
With some small changes this can be more generalized.
But you want to do something different. You dont want to move data or information between the application and the database. You want to use efcore to create a slq-procedure on the fly and run that on the server. The problem is that ef core is not realy build to do that. But maybe there are ways around that. One way i could think of is to use ef-core to build a query, get the query string and then insert that string into another sql-string to run on the server.
Getting the query string is currently not easy but apparently it will be with EF Core 5.0. Then you could do this:
var queryable = db.Table.AsQueryable()
.Where(o => o.ForeignKey == fKey)
.Where(o => o.OtherColumn == false);
var queryString=queryable.ToQueryString();
db.Database.ExecuteSqlRaw("delete from Table where PK in("+queryString+")" )
And yes that is terribly hacky and i would not recommend that. I would recommend to write procedures and functions on the databaseServer because this is not something ef-core should be used for. And then you can still run those functions from ef-core and pass parameters.
I would suggest using temp tables to do an operation like this. You would create a mirror temp table, bulk add the records to keep or delete to the temp table and then execute a delete operation that looks for records in/not in that temp table. Try using a library such as PgPartner to accomplish bulk additions and temp table creation very easily.
Check out PgPartner: https://www.nuget.org/packages/PgPartner/
https://github.com/SourceKor/PgPartner
Disclaimer: I'm the owner of the project Entity Framework Plus
Your scenario look to be something that our Batch Delete features could handle: https://entityframework-plus.net/batch-delete
Using (var db = new DbContext)
var queryable = db.Table.AsQueryable()
.Where(o => o.ForeignKey == fKey)
.Where(o => o.OtherColumn == false);
queryable.Delete();
Entities are not loaded in the application, and only a SQL is executed as you specified.

Updateing a Table with a Stored Procedure or Functions in Catel

I've set up a database with EF6 and Code First and I am using Catel's Repository Pattern to communicate with the database.
Now, I am curious as to how you would call a stored procedure (or even a Scalar Valued Function) on my database using Catel. Any suggestions?
You should still be able to call the stored procedure using the DbContext itself as you usually would:
using (var dbContextManager = DbContextManager<MyEntities>.GetManager())
{
var dbContext = dbContextManager.DbContext;
var result = dbContext.Database.SqlQuery<ReturnType>("storedProcedureName", params);
}
https://msdn.microsoft.com/en-us/library/gg696545(v=vs.113).aspx

Code first filetable in SQL Server

Trying to take advantage of the FileTables feature in SQL Server 2012 in my current MVC5 project. Does anyone have any examples of how to create the file table "table" using code first? All of my tables, indexes, etc. are done using code first and I'd like to continue that practice here.
Unfortunately I cannot help you with FileTable, but this example of FileStream (similar thing in many ways) works quite well.
The decision is available here: "WEB API FILE UPLOAD WITH MS SQL SERVER FILETABLE"
https://damienbod.wordpress.com/2014/04/08/web-api-file-upload-with-ms-sql-server-filetable/
You can add custom SQL in a Code First Migration.
Create a migration Add-Migration
Put In some Custom SQL to Enable Filestreams
Update the db with Update-Database
Example migration with custom SQL:
public partial class AddFileStreamMigration: DbMigration
{
public override void Up()
{
var customSql = #"ALTER DATABASE Photos
SET FILESTREAM (NON_TRANSACTED_ACCESS = FULL)
GO
etc...";
Sql(customSql );
}
public override void Down()
{
//Make sure you put in roll back SQL too!
}
}
```

How to use table valued function in entity framework code first approach?

i am working on a project using Entity Framework and now i got a situation where i need to use table valued function which returns table with 2 columns, hence i searched a lot and i came to know that we use table valued functions in Database first approach while i needed it in Code first.
here is the situation
i have a table with two columns
Table1
Id int PK
priority int
i want to use this table in my query in EF.
Is their any way i can use Table Valued function?
We can do this by using the c# code generated by the CLR for Database first approach
you can refer this url for the full description
http://blogs.msdn.com/b/adonet/archive/2011/06/30/walkthrough-table-valued-functions-june-ctp.aspx
i had used this code and it worked fine for me
[EdmFunction("NorthwindEntities", "GetDetailsForOrder")]
public IQueryable<Order_Detail> GetDetailsForOrder(Nullable<global::System.Int32> oid)
{
ObjectParameter oidParameter;
if (oid.HasValue)
{
oidParameter = new ObjectParameter("Oid", oid);
}
else
{
oidParameter = new ObjectParameter("Oid", typeof(global::System.Int32));
}
return base.CreateQuery<Order_Detail>("[NorthwindEntities].[GetDetailsForOrder](#Oid)", oidParameter);
}
I created a custom model convention which allows using store functions in CodeFirst in EF6.1. The convention is available on NuGet http://www.nuget.org/packages/EntityFramework.CodeFirstStoreFunctions. Here is the link to the blogpost containing all the details: http://blog.3d-logic.com/2014/04/09/support-for-store-functions-tvfs-and-stored-procs-in-entity-framework-6-1/