Define the Data Model and Set the Initial Data(定义数据模型并设置初始数据 )
This topic explains how to implement entity classes for your application. It also describes the basics of automatic user interface construction based on a data model; this includes information on how to do the following:
本主题介绍如何为您的应用程序实现实体类。它还描述了基于数据模型的自动用户交互界面构建的基础知识;这包括有关如何执行以下操作的信息:
- Create entity classes.(创建实体类。 )
- Use migrations to propagate the data model structure changes to the database.(使用迁移将数据模型结构更改传播到数据库。 )
- Populate the database with initial data.(用初始数据填充数据库。)
Entity classes do not depend on the application UI. Implement them in a platform-independent module project. This code architecture allows XAF and non-XAF applications to share entities (for instance, with a Web API Service and .NET MAUI, JavaScript, or Blazor clients).
实体类不依赖于应用程序UI。在platform-independent模块项目中实现它们。此代码体系结构允许XAF和非XAF应用程序共享实体(例如,使用Web API Service和. NET MAUI、JavaScript或Blazor客户端)。
The application’s data model consists of one logical block:
应用程序的数据模型由两个逻辑块组成:
- Marketing: the Customer and Testimonial classes.
- 市场营销:客户和推荐课程。
Add Entity Classes for the Marketing Group(为营销组添加实体类)
Go to the SimpleProjectManager.Module project and right-click the Business Objects folder. Choose Add | Class… in the context menu. Specify Customer.cs as the new class name and click Add. Replace auto-generated code with the following class declaration:
转到SimpleProjectManager. Module项目并右键单击Business Objects文件夹。在上下文菜单中选择Add|Class…。将Custore.cs指定为新的类名,然后单击Add。将自动生成的代码替换为以下类声明:
C#
using DevExpress.ExpressApp.DC;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl.EF;namespace SimpleProjectManager.Module.BusinessObjects
{// Use this attribute to place a navigation item that corresponds to the entity class in the specified navigation group.[NavigationItem("Marketing")]// Inherit your entity classes from the BaseObject class to support CRUD operations for the declared objects automatically.public class Customer : BaseObject{public virtual String FirstName { get; set; }public virtual String LastName { get; set; }// Use this attribute to specify the maximum number of characters that the property's editor can contain.[FieldSize(255)]public virtual String Email { get; set; }public virtual String Company { get; set; }public virtual String Occupation { get; set; }public virtual IList<Testimonial> Testimonials { get; set; } =new ObservableCollection<Testimonial>();public String FullName{get { return ObjectFormatter.Format("{FirstName} {LastName} ({Company})",this, EmptyEntriesMode.RemoveDelimiterWhenEntryIsEmpty); }}// Use this attribute to show or hide a column with the property's values in a List View.[VisibleInListView(false)]// Use this attribute to specify dimensions of an image property editor.[ImageEditor(ListViewImageEditorCustomHeight = 75, DetailViewImageEditorFixedHeight = 150)]public virtual MediaDataObject Photo { get; set; }}
}
In the same manner, create the Testimonial class. Replace the generated class declaration with the following code:
以同样的方式,创建Testimonial类。将生成的类声明替换为以下代码:
C#
using DevExpress.ExpressApp.DC;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl.EF;namespace SimpleProjectManager.Module.BusinessObjects
{[NavigationItem("Marketing")]
public class Testimonial : BaseObject
{
public virtual string Quote { get; set; }[FieldSize(512)]
public virtual string Highlight { get; set; }[VisibleInListView(false)]
public virtual DateTime CreatedOn { get; set; }public virtual string Tags { get; set; }public virtual IList<Customer> Customers { get; set; } = new ObservableCollection<Customer>();}
}
The Testimonials collection property in the Customer class defines the first part of the many-to-many relationship between the Customer and Testimonial entities. The declaration of the Customers collection property in the Testimonial class completes the relationship.
客户类中的Testimonial集合属性定义了客户和Testimonial实体之间多对多关系的第一部分。Testimonial类中客户集合属性的声明完成了关系。
The most common relationship creation practice is to define properties on both ends of the relationship. At the same time, it is sufficient to add only the reference property (the “one” part). This property establishes the one-to-many relationship between entities, and Entity Framework Core automatically creates a foreign key to the related table in a database.
最常见的关系创建实践是在关系的两端定义属性。同时,只添加引用属性(“一”部分)就足够了。该属性建立实体之间的一对多关系,实体框架核心自动创建数据库中相关表的外键。
You can use either of these techniques, but when you omit the “many” part of the relationship, XAF does not create an editor for the omitted collection property in the Detail View of the entity class.
您可以使用这些技术中的任何一种,但是当您省略关系的“许多”部分时,XAF不会为实体类的详细信息视图中省略的集合属性创建编辑器。
Go to the SimpleProjectManager.Module\BusinessObjects\MySolutionDbContext file and add the following properties to the SimpleProjectManagerEFCoreDbContext entity container class:
转到SimpleProjectManager. Module\BusinessObjects\MySolutionDbContext文件并将以下属性添加到SimpleProjectManagerEFCoreDbContext实体容器类:
C#
using SimpleProjectManager.Module.BusinessObjects;namespace SimpleProjectManager.Module.BusinessObjects {public class SimpleProjectManagerEFCoreDbContext : DbContext {//...public DbSet<Customer> Customers { get; set; }public DbSet<Testimonial> Testimonials { get; set; }}
}
These properties store collections of entity class objects. For each collection, XAF creates a table with the same name in the database and then maps the collection to the table.
这些属性存储实体类对象的集合。对于每个集合,XAF 在数据库中创建一个同名的表,然后将该集合映射到该表。
Set up Migrations(设置迁移)
Since this tutorial uses Entity Framework Core, changes to the application’s data model may cause database-related exceptions when you run the application. An exception occurs if the database structure does not correspond to the structure of the data model classes.
由于本教程使用Entity Framework Core,因此在运行应用程序时,对应用程序数据模型的更改可能会导致与数据库相关的异常。如果数据库结构与数据模型类的结构不对应,则会发生异常。
In this tutorial, we use migrations to update the database schema because this feature is native to EF Core and is quick to implement. Every time you change the data model of your application, create a migration and update the database. To do this, follow the steps below.
在本教程中,我们使用迁移来更新数据库模式,因为此功能是EF Core的原生功能,并且可以快速实现。每次更改应用程序的数据模型时,请创建迁移并更新数据库。为此,请按照以下步骤操作。
Important(重要提醒)
Delete an existing database if there is one before you proceed, because Entity Framework Core does not take the existing database schema into consideration when it generates the first migration.
在继续之前删除现有数据库(如果有),因为Entity Framework Core在生成第一次迁移时不会考虑现有数据库模式。
1.Add the Microsoft.EntityFrameworkCore.Tools NuGet package to the SimpleProjectManager.Module project. Build the solution.
将Microsoft.EntityFrameworkCore.Tools NuGet包添加到SimpleProjectManager。模块项目。构建解决方案。
Note(注)
The package’s version must match the version of Entity Framework Core supported in XAF.
包的版本必须与XAF支持的Entity Framework Core版本匹配。
Currently, we support Entity Framework Core 8.x.x. To find out which precise version you have, check the Microsoft.EntityFrameworkCore package in the dependencies of the YourProjectName.Module project.
目前,我们支持Entity Framework Core 8. x.x。要了解您拥有的精确版本,请查看YourProjectName.Module项目依赖项中的Microsoft.EntityFrameworkCore包。
2.In the SimpleProjectManager.Module project, go to the BusinessObjects folder and open the SimpleProjectManagerDbContext.cs file. Replace the declaration of the SimpleProjectManagerDesignTimeDbContextFactory class with the code below:
在SimpleProjectManager. Module项目中,转到BusinessObjects文件夹,打开SimpleProjectManagerDbContext.cs文件。用下面的代码替换SimpleProjectManagerDesignTimeDbContextFactory类的声明:
C#
namespace SimpleProjectManager.Module.BusinessObjects;
//...public class SimpleProjectManagerDesignTimeDbContextFactory : IDesignTimeDbContextFactory<SimpleProjectManagerEFCoreDbContext> {public SimpleProjectManagerEFCoreDbContext CreateDbContext(string[] args) {// Throw new InvalidOperationException("Make sure that the database connection string and connection provider are correct. After that, uncomment the code below and remove this exception.");var optionsBuilder = new DbContextOptionsBuilder<SimpleProjectManagerEFCoreDbContext>();optionsBuilder.UseSqlServer("Integrated Security=SSPI;Pooling=false;Data Source=(localdb)\\mssqllocaldb;Initial Catalog=SimpleProjectManager");// Automatically implements the INotifyPropertyChanged interface in the business objectsoptionsBuilder.UseChangeTrackingProxies();optionsBuilder.UseObjectSpaceLinkProxies();return new SimpleProjectManagerEFCoreDbContext(optionsBuilder.Options);}
}
In the above code sample, the optionsBuilder.UseChangeTrackingProxies method enables the change-tracking proxies extension so that the application’s UI correctly reflects changes in data model. Refer to the Change Tracking in EF Core DbContext and Performance Considerations article for more information on change tracking in XAF applications with Entity Framework Core data models.
在上面的代码示例中,optionsBuilder.UseChangeTrackingProxies方法启用更改跟踪代理扩展,以便应用程序的UI正确反映数据模型中的更改。有关使用Entity Framework Core数据模型的XAF应用程序中更改跟踪的更多信息,请参阅EF Core DbContext和性能注意事项中的更改跟踪文章。
3.In Visual Studio, open the Package Manager Console and use the following command to add a migration:
在Visual Studio中,打开包管理器控制台并使用以下命令添加迁移:
console
add-migration MyInitialMigrationName -StartupProject “SimpleProjectManager.Module” -Project “SimpleProjectManager.Module”
4.Update the database with the following command:
使用以下命令更新数据库:
console
update-database -StartupProject “SimpleProjectManager.Module” -Project “SimpleProjectManager.Module”
You must update the database whenever you change the data model of your application, for example, when you add, rename, or delete a class or property. To do this, repeat steps 3 and 4 of this tutorial. Make sure to use a unique migration name for each new migration.
每当您更改应用程序的数据模型时,您都必须更新数据库,例如,当您添加、重命名或删除类或属性时。为此,请重复本教程的步骤3和4。确保为每个新迁移使用唯一的迁移名称。
Populate the Database with Initial Data(用初始数据填充数据库)
Expand the SimpleProjectManager.Module project in the Solution Explorer and go to the DatabaseUpdate folder. Open the Updater.cs file and add the following code to the ModuleUpdater.UpdateDatabaseAfterUpdateSchema method:
展开SimpleProjectManager。解决方案资源管理器中的模块项目并转到数据库更新文件夹。打开Updater. cs文件并将以下代码添加到ModuleUpdater。UpdateDatabaseAfterUpdateSchema方法:
C#
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Updating;
using SimpleProjectManager.Module.BusinessObjects;
// ...public class Updater : ModuleUpdater {//...public override void UpdateDatabaseAfterUpdateSchema() {base.UpdateDatabaseAfterUpdateSchema();Customer customer = ObjectSpace.FirstOrDefault<Customer>(c =>c.FirstName == "Ann" && c.LastName == "Devon");if (customer == null){customer = ObjectSpace.CreateObject<Customer>();customer.FirstName = "Ann";customer.LastName = "Devon";customer.Company = "Eastern Connection";}ObjectSpace.CommitChanges(); // Uncomment this line to persist created objects.}// ...
}
XAF uses an Object Space to manage persistent objects. Refer to the following topic for detailed information: Create, Read, Update and Delete Data).
XAF使用对象空间来管理持久对象。有关详细信息,请参阅以下主题:创建、读取、更新和删除数据)。
Note(注)
For more information on how to populate the database with initial data, review the following lesson of the In-Depth .NET WinForms & Blazor UI Tutorial: Supply Initial Data.
有关如何使用初始数据填充数据库的更多信息,请查看深入的以下课程。NET WinForms和Blazor UI教程:提供初始数据。
Run the Application(运行应用程序)
Click Start Debugging or press F5.
单击开始调试或按F5。
XAF generates a user interface based on the specified data structures. The navigation control contains items that correspond to the entity classes you created. List and Detail Views support CRUD operations and other functionality, such as navigation, search, filter, or print. Detail Views contain editors that display different entity class properties. For more information about built-in editors, refer to the following topic: Data Types Supported by built-in Editors.
XAF根据指定的数据结构生成用户交互界面。导航控件包含与您创建的实体类相对应的项目。列表和详细视图支持CRUD操作和其他功能,如导航、搜索、过滤或打印。详细视图包含显示不同实体类属性的编辑器。有关内置编辑器的更多信息,请参阅以下主题:内置编辑器支持的数据类型。
Lookup and collection editors display properties that constitute a relationship between entities. For example, the Testimonials group in the Customer Detail View is how XAF renders the Testimonials collection property. To create new objects in the Testimonials collection, use the New button in this tab. The Link button allows users to add references to existing Testimonial objects.
查找和集合编辑器显示构成实体之间关系的属性。例如,客户详细信息视图中的Testimonial组是XAF呈现Testimonial集合属性的方式。要在Testimonial集合中创建新对象,请使用此选项卡中的New按钮。Link按钮允许用户添加对现有Testimonial对象的引用。
ASP.NET Core Blazor
Windows Forms
Note(注)
For additional information on UI generation, refer to the following topics: List View Column Generation and View Items Layout Generation.
有关UI生成的其他信息,请参阅以下主题:列表视图列生成和视图项布局生成。
Next Lesson(下一课)
Customize the Application UI and Behavior
自定义应用程序UI和行为