(nopCommerce 4.2) 如何执行存储过程并得到 return 模型。?

(nopCommerce 4.2) How to execute stored procedure and get return model.?

我正在使用 nopCommerce 4.2,所有 table 相关的 CRUD 操作都运行良好。 我只是找不到执行存储过程和检索产品列表模型的方法。我试过使用下面的代码。

var pProductIds = _dataProvider.GetStringParameter("ProductIds", productIds);
var elasticIndexProducts =
_dbContext.QueryFromSql<ProductModel>("Exec SP_GetProductsForElastic @ProductIds", pProductIds).ToList();

但我收到一条错误消息 "Cannot create a DbSet for 'ProductModel' because this type is not included in the model for the context."

这是我的模型

public class ProductModel
    {
        public DateTime IndexDate { get; set; }
        public string ProductId { get; set; }
        public string PartNumber { get; set; }
        public string Name { get; set; }
        public string MetaKeywords { get; set; }
        public string MetaDescription { get; set; }
        public string MetaTitle { get; set; }
        public int LimitedToStores { get; set; }
        public string ShortDescription { get; set; }
        public string FullDescription { get; set; }
        public string SeName { get; set; }
}

nopCommerce 插件启动

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Nop.Core.Infrastructure;
using Nop.Web.Framework.Infrastructure.Extensions;


namespace JM.Plugin.Core
{
    /// <summary>
    /// Represents object for the configuring plugin DB context on application startup
    /// </summary>
    public class PluginDbStartup : INopStartup
    {
        /// <summary>
        /// Add and configure any of the middleware
        /// </summary>
        /// <param name="services">Collection of service descriptors</param>
        /// <param name="configuration">Configuration of the application</param>
        public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
        {
            //add object context
            services.AddDbContext<JM_Core_ObjectContext>(optionsBuilder =>
            {
                optionsBuilder.UseSqlServerWithLazyLoading(services);
            });
        }

        /// <summary>
        /// Configure the using of added middleware
        /// </summary>
        /// <param name="application">Builder for configuring an application's request pipeline</param>
        public void Configure(IApplicationBuilder application)
        {
        }

        /// <summary>
        /// Gets order of this startup configuration implementation
        /// </summary>
        public int Order => 11;
    }
}

这是我的插件对象上下文class

public class JM_Core_ObjectContext : DbContext, IDbContext
    {
        #region Ctor

        public JM_Core_ObjectContext(DbContextOptions<JM_Core_ObjectContext> options) : base(options)
        {
        }

        #endregion

        #region Utilities

        /// <summary>
        /// Further configuration the model
        /// </summary>
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.ApplyConfiguration(new JMStoreMap());
            modelBuilder.ApplyConfiguration(new JMPictureMap());
            modelBuilder.ApplyConfiguration(new JMTestimonialMap());
            modelBuilder.ApplyConfiguration(new JMBannerMap());

            modelBuilder.ApplyConfiguration(new QuoteMap());
            modelBuilder.ApplyConfiguration(new QuoteItemMap());
            modelBuilder.ApplyConfiguration(new QuoteCustomerMap());
            modelBuilder.ApplyConfiguration(new QuoteChangeLogMap());
            modelBuilder.ApplyConfiguration(new JMShoppingCartItemMap());
            modelBuilder.ApplyConfiguration(new ProductInquiryMap());
            modelBuilder.ApplyConfiguration(new SearchFilterMap());

            base.OnModelCreating(modelBuilder);
        }

        #endregion
}

QueryFromSql<>

我刚刚找到一种方法来执行存储过程并检索产品列表模型。我不知道这是否是标准方法。但是我解决了我的需求。

您需要为您的 return 模型创建一个实体映射 class 并向数据库上下文模型构建器注册。请参考以下示例。

Return 型号 class

    public partial class ElasticIndexGroupProductEntity
    {
        public int ProductId { get; set; }
        public string Name { get; set; }           
        public bool LimitedToStores { get; set; }           
        public string FullDescription { get; set; }
        public string SeName { get; set; }
        public string AssociatedProducts { get; set; }
        public bool StockAvailability { get; set; }
   }

创建实体映射class

    public partial class ElasticIndexGroupProductEntityMap :   NopQueryTypeConfiguration<ElasticIndexGroupProductEntity>
    {
       //no need to implement anything here
    }

使用数据库上下文注册映射

       public class JM_Context : DbContext, IDbContext
       {
           public JM_Context(DbContextOptions<JM_Context> options): base(options)
           {

           }

           protected override void OnModelCreating(ModelBuilder modelBuilder)
           {
               modelBuilder.ApplyConfiguration(new ElasticIndexGroupProductEntityMap());
               base.OnModelCreating(modelBuilder);
           }
        }

存储过程示例。 (异步是可选的)

public async Task<IList<ElasticIndexGroupProduct>> GetElasticGroupProducts(int[] productIds)
{
    try
    {              
        var pProductIds = _dataProvider.GetStringParameter("ProductIds", string.Join(",", productIds));

        var groupProductsToIndex = await Task.WhenAll
        (
            _jmContext.QueryFromSql<ElasticIndexGroupProductEntity>("Exec SP_GetProductsForElastic", pProductIds).ToList()                   
        );               
        return groupProductsToIndex;
    }
    catch (Exception ex)
    {
        _loggerService.Error("[Elastic Search Indexing] Get Elastic Group Products Failed.", ex);
        return null;
    }           
}