0

I am using Entity frame work 6.0.0.0.I had an sql function which return 3 column 2 guid and one varchar (userid,ticketid,number). but how to call this custom sql function with out using ADO.net components. AS Iam using entity frame work (code first approach).

  • 1
    If I'm not mistaking - Possible duplicate of [Calling a SQL User-defined function in a LINQ query](http://stackoverflow.com/questions/20131632/calling-a-sql-user-defined-function-in-a-linq-query) – Gilad Green Nov 03 '16 at 10:56
  • 1
    This might be closer: [Entity Framework 6 Code First Custom Functions](http://stackoverflow.com/q/29517627/6400526) – Gilad Green Nov 03 '16 at 10:58
  • Thanks for the answer.But I currently solve my problem by creating an SP to call that User defined SQL function and call that SP using c# code.. But all i want to Know is that is there any elegent way of calling Userdefined function that resides in the datatbase using entityframe work(version 6.0.0.0) c# code... – user3811011 Nov 04 '16 at 06:36

1 Answers1

0

I had the same: a class derived from DbContext, with several DbSet properties and one stored procedure. I added three functions:

  • Check if the stored procedure exists
  • Create or Alter the stored procedure (needed in case of migration)
  • Call the stored procedure.

Your question is about the last part. You might also want the other ones, so here are the three functions

public class InvoiceContext : DbContext
{
    // DbSet properties left out

    #region stored procedures
    private const string StoredProcedureNameProcessUsageCosts = "processusagecosts";

    public void CallStoredProcedureProcessUsageCosts(UsageCosts usageCosts)
    {
        object[] functionParameters = new object[]
        {
            new SqlParameter(@"ReportDate", usageCosts.ReportPeriod),
            new SqlParameter(@"CustomerContractId", usageCosts.CustomerContractId),
            new SqlParameter(@"CallType", usageCosts.CallType),
            new SqlParameter(@"TariffGroup", usageCosts.TariffGroup),
            new SqlParameter(@"VatValue", usageCosts.VatValue),
            new SqlParameter(@"PurchaseCosts", usageCosts.PurchaseCosts),
            new SqlParameter(@"RetailCosts", usageCosts.RetailCosts),
        };

        const string sqlCommand = @"Exec " + StoredProcedureNameProcessUsageCosts
            + " @ReportDate, @CustomerContractId, @CallType, @TariffGroup, @VatValue,"
            + " @PurchaseCosts, @RetailCosts";
        this.Database.ExecuteSqlCommand(sqlCommand, functionParameters);
    }

    public bool StoredProcedureProcessUsageCostsExists()
    {
        return this.Exists(StoredProcedureNameProcessUsageCosts);
    }

    public void CreateProcedureProcessUsageCosts(bool forceRecreate)
    {
        bool storedProcedureExists = this.Exists (StoredProcedureNameUpdateUsageCosts);

        // only create (or update) if not exists or if forceRecreate:
        if (!storedProcedureExists || forceRecreate)
        {   // create or alter:
            var x = new StringBuilder();

            // ALTER or CREATE?
            if (!storedProcedureExists)
            {
                x.Append(@"CREATE");
            }
            else
            {
                x.Append(@"ALTER");
            }

            // procedure name:
            x.Append(@" procedure ");
            x.AppendLine(StoredProcedureNameProcessUsageCosts);

            // parameters:
            x.AppendLine(@"@ReportPeriod int,");
            x.AppendLine(@"@CustomerContractId bigint,");
            x.AppendLine(@"@CallType nvarChar(80),");
            x.AppendLine(@"@TariffGroup nvarChar(80),");
            x.AppendLine(@"@VatValue decimal(18, 2),");
            x.AppendLine(@"@PurchaseCosts decimal(18, 2),");
            x.AppendLine(@"@RetailCosts decimal(18, 2)");

            // code
            x.AppendLine(@"as");
            x.AppendLine(@"begin");
            x.AppendLine(@"Merge [usagecosts]");
            x.AppendLine(@"Using (Select @ReportPeriod as reportperiod,");
            x.AppendLine(@"              @CustomerContractId as customercontractId,");
            x.AppendLine(@"              @CallType as calltype,");
            x.AppendLine(@"              @TariffGroup as tariffgroup,");
            x.AppendLine(@"              @VatValue as vatvalue)");
            x.AppendLine(@"              As tmp ");
            x.AppendLine(@"On ([usagecosts].[reportperiod] = tmp.reportperiod");
            x.AppendLine(@"AND [usagecosts].[customercontractId] = tmp.customercontractid");
            x.AppendLine(@"AND [usagecosts].[calltype] = tmp.calltype");
            x.AppendLine(@"AND [usagecosts].[tariffgroup] = tmp.tariffgroup");
            x.AppendLine(@"AND [usagecosts].[vatvalue] = tmp.Vatvalue)");
            x.AppendLine(@"When Matched Then ");
            x.AppendLine(@"    Update Set [usagecosts].[purchasecosts] = [usagecosts].[purchasecosts] + @purchasecosts,");
            x.AppendLine(@"               [usagecosts].[retailcosts] = [usagecosts].[retailcosts] + @retailcosts");
            x.AppendLine(@"When Not Matched Then");
            x.AppendLine(@"    Insert (ReportPeriod, CustomerContractId, calltype, tariffgroup, vatvalue, purchasecosts, retailcosts)");
            x.AppendLine(@"    Values (@reportPeriod, @CustomerContractId, @CallType, @TariffGroup, @VatValue, @PurchaseCosts, @RetailCosts);");
            x.AppendLine(@"end");
            this.Database.ExecuteSqlCommand(x.ToString());
        }
        // else: procedure exists and no forced recreate, nothing to do
    }
    #endregion stored procedures
}

Usage:

Call the Stored Procedure

using (var dbContext - new InvoiceContext(...))
{
    UsageCosts params = new UsageCosts()
    {
        ...
    };
    dbContext.CallStoredProcedureUsageCost(params);
}

Create the stored procedure

Do this for instance in InitializeDataBase during initial seeding of the database, or in one of your migration functions

public override void InitializeDatabase(InvoiceContext context)
{
     // if not exists, create the stored procedure
     context.CreateProcedureProcessUsageCosts(false);
}
Harald Coppoolse
  • 28,834
  • 7
  • 67
  • 116
  • Thanks for the answer.But I currently solve my problem by creating an SP to call that User defined SQL function and call that SP using c# code.. But all i want to Know is that is there any elegent way of calling Userdefined function that resides in the datatbase using entityframe work(version 6.0.0.0) c# code... – user3811011 Nov 04 '16 at 06:31
  • Well apparently there is an elegant way of calling a user defined function that resides in the database using EntityFramework. As I showed above, this is the function System.Data.Entity.Database.ExecuteSqlCommand which is accessible via DbContext.Database – Harald Coppoolse Nov 04 '16 at 07:35