EF6學習筆記十一:調用、自動生成存儲過程


要專業系統地學習EF前往《你必須掌握的Entity Framework 6.x與Core 2.0》這本書的作者(汪鵬,Jeffcky)的博客:https://www.cnblogs.com/CreateMyself/

前面說到EF中的原始查詢,就是寫SQL語句執行

那么還有存儲過程的調用也是通過那幾個方法來的

調用查詢數據的存儲過程使用:ctx.Database.SqlQuery<T>()  或者 ctx.DbSet<T>.SqlQuery()

調用Insert、Update、Delete操作的存儲過程使用:ExceuteSqlCommand()或者ExceuteSqlCommandAsync()

調用存儲過程

我們先手動地添加一個存儲過程:select * from tb_products

create procedure GetProducts
as
begin
set nocount on;
select * from tb_Products;
set nocount off;
end
go
View Code

緊接着調用它,可以

var res = ctx.Database.SqlQuery<Product>("dbo.GetProducts");
Console.WriteLine(JsonConvert.SerializeObject(res,set));
View Code

然后再創建一個存儲過程:select id,name from tb_products

create procedure GetProducts2
as
begin
select id,[name] from tb_Products
end
go
View Code

接收類型的屬性數量和返回數據集的字段數量不一致,報錯。得自己另外定義類型去接收

var res = ctx.Database.SqlQuery<Product>("dbo.getproducts2");
Console.WriteLine(JsonConvert.SerializeObject(res));
//  未經處理的異常:  System.Data.Entity.Core.EntityCommandExecutionException: The data reader is incompatible with the specified 'CodeFirstNamespace.Product'. A member of the type, 'Price', does not have a corresponding column in the data reader with the same name.
View Code

 來看看帶參數的存儲過程,在方法中該怎么寫

-- 傳遞參數,name
create procedure GetProductsByName
(
@name as nvarchar(50)
)
as
begin
select *from tb_Products where [Name] =@name;
end
go

--  執行
exec GetProductsByName '磚頭'
go
View Code
// 一個參數name
var parameter = new SqlParameter("@name","水泥");
var res = ctx.Database.SqlQuery<Product>("dbo.getproductsByName @name",parameter);
Console.WriteLine(JsonConvert.SerializeObject(res));
//  [{"Order":null,"Name":"水泥","Price":50.00,"Unit":"袋","FK_Order_Id":"469b82be-8139-4e67-b566-5b2b5f6d838d","Id":"d951e96d-a581-4f87-a567-bedb4c24eca3","AddTime":"2019-01-15T10:28:00.653"}]
View Code

 來看看多個參數的存儲過程

--  兩個參數,id,price
create procedure GetProducts3
(
@id as nvarchar(36), 
@price as decimal(18,2)
)
as
begin 
select * from tb_Products where id =@id and Price = @price
end
go
View Code
//  兩個參數
var parameterList = new List<SqlParameter>
     {
            new SqlParameter(){ ParameterName="@id",SqlDbType = System.Data.SqlDbType.NVarChar,Value ="6495f22b-f1ef-4bd2-b81e-c49eaf6e2f21"},
            new SqlParameter(){ ParameterName="@price",SqlDbType=System.Data.SqlDbType.Decimal,Value=5}
       };
var parameterArr = parameterList.ToArray();
var res = ctx.Database.SqlQuery<Product>("dbo.getproducts3 @id,@price",parameterArr);
Console.WriteLine(JsonConvert.SerializeObject(res));
//[{"Order":null,"Name":"蘋果","Price":5.00,"Unit":"斤","FK_Order_Id":"e18757db-1db8-4f7f-b702-79138709b304","Id":"6495f22b-f1ef-4bd2-b81e-c49eaf6e2f21","AddTime":"2019-01-15T10:35:03.36"}]
// 簡直沒有問題
View Code

 上面的都是執行的查詢操作,來看看添加操作的存儲過程,我們使用ExcuteSqlCommand()方法

--  添加數據
create procedure AddProduct
(
@name as nvarchar(50),
@price as decimal(18,2),
@unit as nvarchar(10)
)
as
begin
insert into tb_Products values(newid(),@name,@price,'469b82be-8139-4e67-b566-5b2b5f6d838d',getdate(),@unit)
end
go
View Code
var parameterList = new List<SqlParameter>
{
    new SqlParameter(){ ParameterName="@name",SqlDbType = System.Data.SqlDbType.NVarChar,Value ="花生"},
    new SqlParameter(){ ParameterName="@price",SqlDbType = System.Data.SqlDbType.Decimal,Value = 4.4},
    new SqlParameter(){ ParameterName ="@unit",SqlDbType = System.Data.SqlDbType.NVarChar,Value=""}
};
var paraArr = parameterList.ToArray();
var res = ctx.Database.ExecuteSqlCommand("dbo.addproduct @name,@price,@unit", paraArr);
Console.WriteLine(res);  //  result : 1
View Code

EF自動生成存儲過程 

 上面的存儲過程都是手動添加,現在我們在OnModelCreating方法中寫配置,讓它自動添加存儲過程

modelBuilder.Entity<Order>().MapToStoredProcedures();
View Code

這樣他會給你生成三個存儲過程

public partial class jinshantest4 : DbMigration
    {
        public override void Up()
        {
            CreateStoredProcedure(
                "dbo.Order_Insert",
                p => new
                    {
                        Id = p.String(maxLength: 128),
                        OrderNO = p.String(),
                        Description = p.String(),
                        AddTime = p.DateTime(),
                    },
                body:
                    @"INSERT [dbo].[tb_Orders]([Id], [OrderNO], [Description], [AddTime])
                      VALUES (@Id, @OrderNO, @Description, @AddTime)"
            );
            
            CreateStoredProcedure(
                "dbo.Order_Update",
                p => new
                    {
                        Id = p.String(maxLength: 128),
                        OrderNO = p.String(),
                        Description = p.String(),
                        AddTime = p.DateTime(),
                    },
                body:
                    @"UPDATE [dbo].[tb_Orders]
                      SET [OrderNO] = @OrderNO, [Description] = @Description, [AddTime] = @AddTime
                      WHERE ([Id] = @Id)"
            );
            
            CreateStoredProcedure(
                "dbo.Order_Delete",
                p => new
                    {
                        Id = p.String(maxLength: 128),
                    },
                body:
                    @"DELETE [dbo].[tb_Orders]
                      WHERE ([Id] = @Id)"
            );
            
        }
        
        public override void Down()
        {
            DropStoredProcedure("dbo.Order_Delete");
            DropStoredProcedure("dbo.Order_Update");
            DropStoredProcedure("dbo.addOrder");
        }
    }
View Code

也可以對它進行詳細配置,比如我指定insert存儲過程的名稱為“orderAdd” 

modelBuilder.Entity<Order>().MapToStoredProcedures(x => x.Insert(a => a.HasName("addOrder")));
View Code

跟新后,可以看到存儲過程都添加 成功了

 

最后來調用一個EF為我們創建的存儲過程

//  添加一個訂單
var parameterList = new List<SqlParameter>
{
    new SqlParameter{ ParameterName="@Id",SqlDbType = System.Data.SqlDbType.NVarChar,Value = Guid.NewGuid().ToString()},
    new SqlParameter{ ParameterName="@OrderNO",SqlDbType = System.Data.SqlDbType.NVarChar,Value ="order435435"},
    new SqlParameter{ ParameterName="@Description",SqlDbType = System.Data.SqlDbType.NVarChar,Value="description4364537ryrtey"},
    new SqlParameter{ ParameterName="@AddTime",SqlDbType = System.Data.SqlDbType.DateTime,Value =DateTime.Now}
};
var paraArr = parameterList.ToArray();
var res = ctx.Database.ExecuteSqlCommand("dbo.addOrder @Id,@OrderNO,@Description,@AddTime",paraArr);
Console.WriteLine(res);  //  result:1
View Code

可以的

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM