1

我正在一个网站上工作,我需要从与我的 Umbraco 数据库相同的 SQL Server 上的另一个数据库中检索价目表。

要求它必须位于单独的数据库中。

我创建了一个新的连接字符串Pricelist并首先使用 EF 数据库。

PriceList存储库:

namespace UmbracoCMS.Repository{
using System;
using System.Collections.Generic;

public partial class Prisliste
{
    public string Kode { get; set; }
    public string Speciale { get; set; }
    public string Ydelsesgruppe { get; set; }
    public string Gruppe { get; set; }
    public string Ydelse { get; set; }
    public string Ydelsestekst { get; set; }
    public string Anaestesi { get; set; }
    public string Indlæggelse { get; set; }
    public Nullable<double> Listepris { get; set; }
    public Nullable<int> WebSort { get; set; }
    public string YdelsesTekstDK { get; set; }
    public string Frapris { get; set; }
    public Nullable<int> Sortering { get; set; }
   } 
}

PriceListController班级:

using System;
using System.Linq;
using System.Web.Mvc;

using UmbracoCMS.Repository;

namespace UmbracoCMS.Controllers{

   public class PriceListController : Umbraco.Web.Mvc.SurfaceController {

   [HttpGet]
   public PartialViewResult GetPriceList(string contentTitle){

      var db = new PricelistContext();


      var query = from b in db.Prislistes orderby b.Speciale select b;

      Console.WriteLine("records in the database:");

      foreach (var item in query)
      {
        Console.WriteLine(item.Speciale);
      }

      return PartialView("~/views/partials/PriceList.cshtml");
    }
  }
}

我想要的是根据文档类型的属性加载治疗价格。我只是不确定如何在 umbraco 中做到这一点,因为我是一个相当新的 umbraco。

因此,当请求处理页面时,我需要获取属性ContentTitle值。使用它来检索所有相同的记录Speciale并将它们显示在列表/表格中。

有一个查询

.where(b.Speciale = contentTitle)

如果有人能提供一点帮助,或者引导我朝着正确的方向前进,那就太好了。

也可以在同一个http请求中完成吗?或者当用户进入处理页面时,我应该使用部分视图或宏同时从 umbraco 数据库和价格表数据库中获取文档类型的属性?

还是有更好的方法来做到这一点?



更新:

非常感谢Ryios的出色回答。

我还有一个问题。

using System;
using System.Linq;
using System.Web.Mvc;

namespace UmbracoCMS.Controllers
{
  public class PriceListSurfaceController : Umbraco.Web.Mvc.SurfaceController
  {

      public ActionResult GetPriceList(string contentTitle)
      {
        
          PricelistContext.RunInContext(db =>
          {
              var result = db.Prislistes.OrderBy(p => p.Speciale);
            
          });

          return View(result);
      }
   }
}

我让它工作了,所以它调用了这个方法,价格表数据库中的数据显示在:

var result = db.Prislistes.OrderBy(p => p.Speciale);

现在我只需要将价格列表再次显示到视图中,这样我就可以显示价格列表或表格。

你对我如何在 Umbraco 中做到这一点有什么建议吗?通常我会在 MVC 中返回一个 ViewModel,例如:

return View(new ListViewModel(result));

并在视图中使用它,例如:

@model Project.ViewModels.ListViewModel

所以我可以遍历它。

但我仍然希望拥有“Home”/“TreatmentPage”文档类型的属性。

我应该使用 partialView 还是有更好的方法?

解决了

如果其他人处于类似情况,我想我想分享它。

控制器:

namespace UmbracoCMS.Controllers
{
    public class PriceListSurfaceController : Umbraco.Web.Mvc.SurfaceController
    {



        public PartialViewResult PriceList(string contentTitle)
        {
            List<Prisliste> result = null; 

            PricelistContext.RunInContext(db =>
            {
                result = db.Prislistes.Where(p => p.Speciale == contentTitle)
                     .OrderBy(p => p.Speciale).ToList();  
            });

            var model = result.Select( pl => new PrislistVm()
           {
               Speciale = pl.Speciale,
               Listepris= pl.Listepris
           });

           return PartialView(model);
       }



   }

}

视图模型:

namespace UmbracoCMS.ViewModels
{
    public class PrislistVm
    {

       public PrislistVm()
       {
           Results = new List<Prisliste>();
       }

       public List<Prisliste> Results { get; set; } 

       public string Speciale { get; set; }
       public double listepris { get; set; }
   }
}

查看/价格表表面:

@model IEnumerable<UmbracoCMS.ViewModels.PrislistVm>
       
@{
     ViewBag.Title = "PriceList";
}

 <h2>PriceList</h2>



      @foreach (var item in Model)
      {
            @item.Speciale
            @item.Listepris
      }
4

1 回答 1

1
  1. 如果像这样加载 EF 上下文,就会发生内存泄漏。我建议使用 llambda 回调创建一个方法来为您包装它。把它放在你的上下文类中。

    public static void RunInContext(Action<PricelistContext> contextCallBack)
    {
        PricelistContext dbContext = null;
        try
        {
            dbContext = new PricelistContext();
            contextCallBack(dbContext);
        }
        finally
        {
            dbContext.Dispose();
            dbContext = null;
        }
    }
    
    //Example Call
    PricelistContext.RunInContext(db => {
        var result = db.PrisListes.OrderBy(p => p.Speciale);
        //loop through your items
    });
    
  2. 要获取 DocumentType 的值,它取决于调用上下文。假设您正在使用附加到文档类型的 Razor 模板,该模板与内容页面相关联。

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
    @{
        Layout = "ContentPageLayout.cshtml";
    }
    @* Call GetPriceList on PriceListController with Parameter contentTitle *@
    @Html.Action("GetPriceList", "PriceListSurface", new { contentTitle =     Model.Content.GetPropertyValue<string>("ContentTitle") });
    

在上面的示例中,我创建了一个文档类型,其中包含一个名为 ContentTitle 的属性,该属性与一个名为 ContentPage 的视图相关联。然后,我在名为“Home”的后台内容部分创建了使用文档类型的内容。给我一个像

http://localhost/home

此外,您的 SurfaceController 将无法正常工作。Umbraco 为表面控制器映射路线的逻辑对表面控制器的命名约定有一些要求。您必须以“SurfaceController”结束类的名称,然后它被称为PriceListSurfaceController,然后它使用名称“PriceListSurface”映射控制器。

这是 SurfaceController 功能的文档。

http://our.umbraco.org/documentation/Reference/Mvc/surface-controllers

使用表面控制器是正确的逻辑。在 UmbracoTemplatePage 中调用数据层代码并不是一个好习惯。1,因为 RazorTemplates 是解释/编译的,而 SurfaceController 是 JIT 编译到 dll 中的,所以 SurfaceController 代码更快。2 因为您可以在 MVC Razor 中进行异步 Controller 调用。如果一切都在视图中,那么将所有内容都转换为异步将变得非常困难。最好将服务器端逻辑保存在控制器中。

或者,您可以劫持 Umbraco 路由并将其替换为不必从 SurfaceController 继承的自定义控制器,这使得它可以将内容呈现给属于或不属于 umbraco 的浏览器。

http://our.umbraco.org/documentation/Reference/Mvc/custom-controllers

您还可以在后台创建一个新部分来管理您的价目表“用于构建一个的 ui 框架是针对 AngularJS 编写的”

http://www.enkelmedia.se/blogg/2013/11/22/creating-custom-sections-in-umbraco-7-part-1.aspx

于 2014-07-02T03:04:29.380 回答