实体框架使用params执行存储过程

时间:2018-06-14 21:05:20

标签: entity-framework asp.net-core procedure

好的,希望不会得到太多的旗帜,但这很烦人。

我的控制器中有一个方法,它调用另一个类的方法:

offerForCreate.Rating = CalculateRating.CreateRating(addOffer);

和整个被叫类:

public class CalculateRating
{
    private readonly DataContext mainContext;

    public CalculateRating(DataContext mainContext)
    {
        this.mainContext = mainContext;
    }

    // calcul rating oferte noi
    public decimal CreateRating(OfferForCreate offer)
    {
        decimal rating = mainContext.Database.FromSql<decimal>("RatingCalculator", offer.locationId, offer.typeId);

        return rating;
    }
}

尝试执行此过程时出错:

  

错误CS1061:'DatabaseFacade'不包含'FromSql'的定义,并且没有扩展方法'FromSql'接受类型'DatabaseFacade'的第一个参数可以找到

和另一个,如果我不在我的控制器中创建CalculateRating类的实例:

  

Controllers \ AnnouncesController.cs(127,37):错误CS0120:非静态字段,方法或属性'CalculateRating.CreateRating(OfferForCreate)

需要对象引用

我看到的每个地方都必须指定实体,但如果我的存储过程使用多个表,我可以指定哪个实体?

Asp.Net核心Web API

1 个答案:

答案 0 :(得分:2)

您可以像这样执行存储过程:

 using (var command = mainContext.Database.GetDbConnection().CreateCommand())
   {
        command.CommandType = System.Data.CommandType.StoredProcedure;
        command.CommandText = "dbo.RatingCalculator";

       var locationIdParam = new System.Data.SqlClient.SqlParameter("@locationId", System.Data.SqlDbType.Int);
       locationIdParam .Value = offer.locationId;

        //DO same for typeId parameter

          //Params to Parameters collection
          command.Parameters.Add(locationIdParam);

       command.Connection.Open();
       return (double)command.ExecuteScalar();
   }

Controllers\AnnouncesController.cs(127,37): error CS0120: An object reference is required for the non-static field, method, or property 'CalculateRating.CreateRating(OfferForCreate)

发生此错误是因为如果您将CalculateRating声明为静态,则无法在非静态字段mainContext中引用。

您应该使用依赖注入创建CalculateRating类的实例。以下是步骤:

  1. 创建一个接口ICalculateRating

    public interface ICalculateRating { decimal CreateRating(OfferForCreate offer); }

  2. 更新CalculateRating类以实现ICalculateRating

  3. 在Startup.cs文件的ConfigureServices方法中注册DBContext和ICalculateRating映射,如下所示:

    services.AddDbContext<DbContext>(opts=> { opts.UseSqlServer("sqlserver conntection string") }, ServiceLifetime.Scoped);

    services.AddTransient<ICalculateRating, CalculateRating>();

  4. 在控制器构造函数中,输入ICalculateRating类型的参数,该参数将在运行时由Microsoft Dependency Injection框架注入:

    private readonly ICalculateRating _calculateRating; public MyController(ICalculateRating calculateRating) { _calculateRating = calculateRating; }

  5. 然后您可以像这样调用方法: offerForCreate.Rating = _calculateRating.CreateRating(addOffer);