简体   繁体   中英

Passing result of procedure from Entity Framework to view

The goal

I'm using Entity Framework with C# + ASP.NET MVC 4 and I have a stored procedure in my database (MySQL). I want to display the result of this procedure on my view.

The problem: I don't know the syntax.

What I have: on my database context (automatic generated by Entity Framework) there is the following code:

public partial class BluMercadosContext : DbContext
{
    public BluMercadosContext()
        : base("name=BluMercadosContext")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    [...]

    public virtual ObjectResult<getProductsListForHome_Result> getProductsListForHome(Nullable<int> inOffer, Nullable<int> categoryId)
    {
        var inOfferParameter = inOffer.HasValue ?
            new ObjectParameter("inOffer", inOffer) :
            new ObjectParameter("inOffer", typeof(int));

        var categoryIdParameter = categoryId.HasValue ?
            new ObjectParameter("categoryId", categoryId) :
            new ObjectParameter("categoryId", typeof(int));

        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<getProductsListForHome_Result>("getProductsListForHome", inOfferParameter, categoryIdParameter);
    }
}

As you can see, there is a method called getProductsListForHome with two parameters. I want to execute this procedure and then display the results on my view.

And I have to pass the result through controller (MVC) or directly from model to my view (MVVM)?

Thanks in advance.

The quick & dirty way:

Call the getProductsListForHome method in your controller:

public ActionResult ProductList(SomeType SomeParamIfYouNeed)
{
  using (BluMercadosContext context = new BluMercadosContextEntities())
  {
    ObjectSet<Product> query = context.Products;
    ObjectResult<Product> queryResult = query.Execute(MergeOption.AppendOnly);
  }

  return PartialView("ProductList", queryResult);
}

A better way:

Call the getProductsListForHome method in a ModelBuilder . That way, your controller stays clean (always remember the rule: a controller method should not exceed 15 lines of code! )
The following example do use an IOC to bind the IProductBuilder with the right implemetation at runtime (you don't have to do the same, just work with the right implementation directly)

ProductController

public ProductController(IProductBuilder productBuilder)
{
  _productBuilder = productBuilder;
}

public ActionResult ProductList(SomeType SomeParamIfYouNeed)
{
  var model = _productBuilder.Get(SomeParamIfYouNeed);

  return PartialView("ProductList", model);
}

ProductBuilder

public List<Product> Get (SomeType SomeParamIfYouNeed)
{
  using (BluMercadosContext context = new BluMercadosContextEntities())
  {
    ObjectSet<Product> query = context.Products;
    ObjectResult<Product> queryResult = query.Execute(MergeOption.AppendOnly);
  }

  return queryResult;
}

An even better way:

Call the getProductsListForHome method in a ProductService . Would be better for SOC . The ProductController will be responsible for returning a model to the view , the ProductBuilder will be in charge of the mapping between the business/domain objects returned by the ProductService and the viewmodel , and finally, the ProductService will be responsible for calling the getProductsListForHome method.

ProductController

public ProductController(IProductBuilder productBuilder)
{
  _productBuilder = productBuilder;
}

public ActionResult ProductList()
{
  var model = _productBuilder.Get();

  return PartialView("ProductList", model);
}

ProductBuilder

public ProductBuilder(IProductService productService)
{
  _productService = productService;
}

public List<Product> Get ()
{
  // Rather than returning the _productService method call, you could do some mapping between what is returned and the model your view needs.
  return _productService.GetProducts();
}

ProductService

public List<Product> GetProducts()
{
  using (BluMercadosContext context = new BluMercadosContextEntities())
  {
    ObjectSet<Product> query = context.Products;
    ObjectResult<Product> queryResult = query.Execute(MergeOption.AppendOnly);
  }

  return queryResult;
}

This code might obviously not compile if you copy-paste it in your project. Its purpose is rather to show you different ways to deal with this kind of situation!

I think you're looking for DbContext.DataBase.SqlQuery()

Creates a raw SQL query that will return elements of the given generic type. The type can be any type that has properties that match the names of the columns returned from the query, or can be a simple primitive type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM