Orchard CMS 连接外部 SQL 服务器

Orchard CMS connect external SQL Server

我打算创建一些页面来显示来自带有 Orchard CMS 的外部 SQL 服务器的数据。看来我需要写一个新的模块来实现这个功能。是否有任何示例或想法来实现此要求?

是的,您将需要编写一个新模块,它提供一个新的内容部分和一个内容部分驱动程序。该驱动程序将负责从外部 SQL 服务器获取数据,您将从驱动程序 returning 的形状上将其设置为 属性。然后形状的视图将显示您的数据。

本教程将指导您编写自定义内容部分:http://docs.orchardproject.net/en/latest/Documentation/Writing-a-content-part/

当你这样做时,确保创建内容部分记录类型,因为你不会从 Orchard 数据库中存储和加载数据 - 你想从中加载数据一个外部数据库。这些是您应该遵循的步骤:

  1. 创建一个新模块
  2. 创建内容部分class
    1. 让你的部分继承自 ContentPart而不是 ContentPart<TRecord> 因为不会有任何 "TRecord".
  3. 创建内容部分驱动程序
    1. Display方法中,通过调用ContentShape方法return一个形状。 确保在 lambda 中添加 SQL 数据访问逻辑。如果您在该 lambda 之外执行此操作,则每次调用使用您的内容部分的内容项时都会调用该数据访问代码。虽然听起来这正是您想要的,但这里有一个涉及 Placement.info 的微妙之处,您可以使用它来确定何时实际渲染您的形状。如果放置逻辑确定不应呈现您的形状,那么您不想白白访问您的外部数据。
  4. 创建一个 Placement.info 文件来配置形状的位置(在呈现的内容项的上下文中)。
  5. 为您在步骤 3.2 中 return 的形状创建 Razor 视图。
  6. 创建一个迁移 class 来定义您的自定义内容部分,以及您要将您的部分添加到的任何内容类型。有关如何创建迁移的详细信息,请参阅 http://docs.orchardproject.net/en/latest/Documentation/Understanding-data-access/

PS。与其直接在驱动程序中实现数据访问代码,我建议您在单独的 class 中实现它。因为你知道,关注点分离等等。然后您可以将该服务注入您的驱动程序。要让您的服务 class 注册到服务容器,请确保为其定义一个接口,该接口本身派生自 IDependency.

一些示例伪代码:

服务代码:

public interface IMyExternalDataStore : IDependency {
   IList<MyExternalDataRecord> GetMyData();
}

public class MyExternalDataStore : IMyExternalDataStore {
   public IList<MyExternalDataRecord> GetMyData() {
      // Connect to your SQL Server database, perhaps using EF, load the data and return it. Could of course also be simply a DataSet.
   }
}

内容部分:

public class MyExternalDataPart : ContentPart {
    // Nothing here, unless you want to include some properties here that influence the data that you want to load. If so, you'll also want to implement the Editor methods in your content part driver, but I'm keeping it simple.
}

内容部分驱动程序:

public class MyExternalDataPartDriver : ContentPartDriver<MyExternalContentPart> {

   private readonly IMyExternalDataStore _dataStore;

   public MyExternalDataPartDriver(IMyExternalDataStore dataStore) {
      _dataStore = dataStore;
   }

   protected override DriverResult Display(SlideShowProPart part, string displayType, dynamic shapeHelper) {

       return ContentShape("Parts_MyExternalData", () => {
          // Notice that we're performing the data access here within the lambda (the so called "shape factory method").
          var data = _dataStore.GetMyData();

          // Notice that I'm creating a property called "MyData"on the shape (which is a dynamic object).
          return shapeHelper.Parts_MyExternalData(MyData: data));
       }
   }
}

Parts_MyExternalData 形状的剃刀视图: 文件名:Parts.MyExternalData.cshtml

@{
   var records = (IList<MyExternalDataRecord>)Model.MyData;
}
<ul>
@foreach(var record in records) {
   <li>@record.ToString()</li>
}
</ul>

Placement.info:

<Placement>
   <Place Parts_MyExternalData="Content:0"/>
</Placement>

迁移:

public class Migrations : DataMigrationImpl {
    public int Create() {

       // Define your content part so that you can attach it to any content type from the UI.
       ContentDefinitionManager.AlterPartDefinition("MyExternalDataPart", part => part.Attachable());

       // Optionally, define a new content type here programmatically or attach it to an existing type.

       return 1;
    }
}