Attach Files to Objects 将文件附加到对象

In this lesson, you will learn how to attach file collections to business objects. For this purpose, the File Attachment module will be added to the application, and the new Resume and PortfolioFileData business classes will be implemented. The Resume class will be used to store and manage a Contact's resume information: a file data collection and a reference to a Contact. The PortfolioFileData class will represent the file data collection item. You will also learn how the file data type properties are displayed and managed in a UI.

在本课中,您将学习如何将文件集合附加到业务对象。为此,文件附件模块将添加到应用程序中,并将实现新的"简历"和"项目组合文件数据"业务类。"简历"类将用于存储和管理联系人的简历信息:文件数据收集和对联系人的引用。包件文件数据类将表示文件数据收集项。您还将了解如何在 UI 中显示和管理文件数据类型属性。

 

Note 注意
Before proceeding, take a moment to review the following lessons.

在继续之前,请花点时间复习以下课程。

  • Implement Custom Business Classes and Reference Properties (XPO/EF)
  • Inherit from the Business Class Library Class (XPO/EF)
  • Set a One-to-Many Relationship (XPO/EF)
  • 实现自定义业务类和参考属性 (XPO/EF)

  • 从商务舱库类 (XPO/EF) 继承

  • 设置一对多关系 (XPO/EF)

  • Add the File Attachments module to your WinForms module project. For this purpose, find the WinModule.cs (WinModule.vb) file in the MySolution.Module.Win project displayed in the Solution Explorer. Double-click this file to invoke the Module Designer. In the Toolbox, expand the DX.19.2: XAF Modules tab. Drag the FileAttachmentsWindowsFormsModule item to the Designer's Required Modules section.
  • 将文件附件模块添加到 WinForms 模块项目中。为此,在 MySolution.module.win 项目中查找WinModule.cs (WinModule.vb) 文件。双击此文件以调用模块设计器。在工具箱中,展开 DX.19.2:XAF 模块选项卡。将文件附件 WindowsForms 模块项目拖动到"设计器所需的模块"部分。

    Tutorial_EM_Lesson1_0

 

  • Add the File Attachments module to your ASP.NET module project. For this purpose, find the WebModule.cs (WebModule.vb) file in the MySolution.Module.Web project displayed in the Solution Explorer. Double-click this file to invoke the Module Designer. In the Toolbox, expand the DX.19.2: XAF Modules tab. Drag the FileAttachmentsAspNetModule item to the Designer's Required Modules section.

  • 将文件附件模块添加到ASP.NET模块项目中。为此,在解决方案资源管理器中显示的 MySolution.module.Web 项目中查找WebModule.cs (WebModule.vb) 文件。双击此文件以调用模块设计器。在工具箱中,展开 DX.19.2:XAF 模块选项卡。将文件附件AspNet模块项目拖动到"设计器所需的模块"部分。

    Tutorial_EM_Lesson1_0_1

  • After you have made changes in the Application Designer, rebuild your solution.
  • 在应用程序设计器中进行更改后,请重新生成解决方案。
  • Add a new Resume business class, as described in the Inherit from the Business Class Library Class (XPO/EF) lesson.
  • 添加新的"简历"业务类,如"从业务类库类继承"一课 (XPO/EF) 中所述。
  • Replace the automatically generated Resume class declaration with the following code.

 

将自动生成的 Resume 类声明替换为以下代码。

eXpress Persistent Objects

 

eXpress 持久对象

using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Xpo;
using MySolution.Module.BusinessObjects;

[DefaultClassOptions]
[ImageName("BO_Resume")]
public class Resume : BaseObject {
   public Resume(Session session) : base(session) {}
   private Contact contact;
   public Contact Contact {
      get { 
         return contact;
      }
      set {
         SetPropertyValue(nameof(Contact), ref contact, value);
      }
   }
  [Aggregated, Association("Resume-PortfolioFileData")]
  public XPCollection<PortfolioFileData> Portfolio {
     get { return GetCollection<PortfolioFileData>(nameof(Portfolio)); }
  }
}

 

Entity Framework

实体框架

using System;
using System.Linq;
using System.ComponentModel;
using System.Collections.Generic;
using DevExpress.Persistent.Base;

namespace MySolution.Module.BusinessObjects {
    [DefaultClassOptions]
    [ImageName("BO_Resume")]
    public class Resume {
        public Resume() {
            Portfolio = new List<PortfolioFileData>();
        }
        [Browsable(false)]
        public Int32 ID { get; protected set; }
        public virtual IList<PortfolioFileData> Portfolio { get; set; }
        public virtual Contact Contact { get; set; }
    }
}

 

public class MySolutionDbContext : DbContext {
    //...
    public DbSet<Resume> Resumes { get; set; }
}

 

public class Contact : Person {
    public Contact() {
        //...
        Resumes = new List<Resume>();
    }
    //...
    public virtual IList<Resume> Resumes { get; set; }
}

 

Declare the PortfolioFileData class, which is the FileAttachmentBase descendant for XPO and FileAttachment - for EF, and DocumentType enumeration (for XPO) as follows.

声明组合文件数据类,这是 XPO 和文件附件的 File 附件Base 子级 - 用于 EF,文档类型枚举(对于 XPO),如下所示。

eXpress Persistent Objects

eXpress 持久对象

public class PortfolioFileData : FileAttachmentBase {
   public PortfolioFileData(Session session) : base(session) {}
   protected Resume resume;
   [Persistent, Association("Resume-PortfolioFileData")]
   public Resume Resume {
      get { return resume; }
      set { 
         SetPropertyValue(nameof(Resume), ref resume, value); 
      }
   }
   public override void AfterConstruction() {
      base.AfterConstruction();
      documentType = DocumentType.Unknown;
   }
   private DocumentType documentType;
   public DocumentType DocumentType {
      get { return documentType; }
      set { SetPropertyValue(nameof(DocumentType), ref documentType, value); }
   }
}
public enum DocumentType { SourceCode = 1, Tests = 2, Documentation = 3,
   Diagrams = 4, ScreenShots = 5, Unknown = 6 };

 

Entity Framework

实体框架

using System;
using System.Linq;
using System.ComponentModel;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl.EF;

namespace MySolution.Module.BusinessObjects {
    [ImageName("BO_FileAttachment")]
    public class PortfolioFileData : FileAttachment {
        public PortfolioFileData()
            : base() {
            DocumentType = DocumentType.Unknown;
        }

        [Browsable(false)]
        public Int32 DocumentType_Int { get; protected set; }
        [System.ComponentModel.DataAnnotations.Required]
        public Resume Resume { get; set; }

        [NotMapped]
        public DocumentType DocumentType {
            get { return (DocumentType)DocumentType_Int; }
            set { DocumentType_Int = (Int32)value; }
        }
    }
}

 

public class MySolutionDbContext : DbContext {
    //...
    public DbSet<PortfolioFileData> PortfolioFileData { get; set; }
    public DbSet<FileAttachment> FileAttachments { get; set; }
}

 

In the code above, you can see that the Resume and PortfolioFileData classes are related with a One-to-Many relationship. Another important point is that in XPO, the PortfolioFileData.DocumentType property is initialized in the AfterConstruction method, which is called after creating the corresponding object.

在上面的代码中,您可以看到"简历"和"项目组合文件数据"类与一对多关系相关。另一个重要点是,在 XPO 中,在创建相应对象后调用的 After 构造方法中初始化了项目组合文件Data.DocumentType 属性。

 

The EF version of code includes a workaround of one noticeable Entity Framework peculiarity. By default, the deletion of a master-object does not cause the deletion of referenced objects. The only thing that happens is the nullification of the links from referenced objects to the master object. Nullification will be successful only if the referenced objects are loaded at the moment of deletion, but if an object is deleted from the List View, this is not always so. To avoid integrity violation, the associations between classes should be configured to allow the referenced objects to be deleted with the master. In the code above, this is done by the [System.ComponentModel.DataAnnotations.Required] attribute of the Resume property in the PortfolioFileData class declaration.

代码的 EF 版本包含一个值得注意的实体框架特性的解决方法。默认情况下,删除主对象不会导致删除引用的对象。唯一发生的情况是从引用对象到主对象的链接无效。仅当在删除时加载引用的对象时,取消将成功,但如果从列表视图中删除对象,则并不总是如此。为了避免完整性冲突,应将类之间的关联配置为允许与主对象一起删除引用的对象。在上面的代码中,这是由[System.组件模型.DataAnnotations.必需] 属性的"简历"属性在组合文件数据类声明中完成的。

Note 注意

Another way to avoid the integrity violation is the use of Fluent APIto call the WillCascadeOnDelete(true) method for the Portfolio-Resume relationship. The Fluent API requests should be located in the DbContext.

避免完整性冲突的另一种方法是使用 Fluent APIto 调用 WillCascadeOnDelete(true) 方法进行项目组合-恢复关系。流畅 API 请求应位于 DbContext 中。

 

Refer to the File Attachment Properties in XPO and File Attachment Properties in Entity Framework topics to learn more about file attachment properties creation.

请参阅 XPO 中的文件附件属性和实体框架中的文件附件属性主题,了解有关文件附件属性创建的详细信息。

  • Run the WinForms or ASP.NET application and create a new Resume object.
  • To specify the File property, attach a file in the Open dialog, invoked via the Add From File... (btn_attach) button.

  • 运行 WinForms 或ASP.NET应用程序并创建新的"简历"对象。

  • 要指定 File 属性,请在"打开"对话框中附加一个文件,该对话框通过"从文件添加..."调用。(btn_attach)按钮。

    Tutorial_EM_Lesson1_1

  • To open or save a file attached to the Portfolio collection, or add a new file, use the Open..., Save As... or Add From File... Actions supplied with the collection.

  • 要打开或保存附加到项目组合集合的文件,或添加新文件,请使用"打开...",另存为...或从文件添加...随集合一起提供的操作。

    Tutorial_EM_Lesson1_3

Tip 指示
To save the file stored within the current FileData object to the specified stream, use the IFileData.SaveToStream method.

要将存储在当前 FileData 对象中的文件保存到指定的流中,请使用 IFileData.SaveToStream 方法。

 

You can see the code demonstrated here in the Resume.cs (Resume.vb) file of the Main Demo installed with XAF. The MainDemo application is installed in %PUBLIC%\Documents\DevExpress Demos 19.2\Components\eXpressApp Framework\MainDemo by default. The ASP.NET version is available online at http://demos.devexpress.com/XAF/MainDemo/

您可以在随 XAF 安装的主演示的Resume.cs (Resume.vb) 文件中演示的代码。主演示应用程序安装在%PUBLIC%\Documents\DevExpress Demos 19.2\Components\eXpressApp Framework\MainDemo by default. The ASP.NET version is available online at http://demos.devexpress.com/XAF/MainDemo/

.

posted @ 2019-12-17 16:18  code first life  阅读(546)  评论(0编辑  收藏  举报