EPR类企业管理系统

在我们现有系统基础上或全新开发,提供定制服务
为您的企业高效快速实施ERP,WMS,MES,CRM管理系统
全面管控物料仓库、销售业务、采购业务、仓库业务
生产过程、质量检验、组织架构、业务报表


定制
QQ:460-3528

开发
QQ群:3360-90194

源码
微信:136-3650-3721

代码和UI中实体之间的关系

在设计业务模型时,可能有必要在业务对象之间设置特定的关系。本主题描述如何设置使用Entity Framework Code First创建的应用程序中可用的实体之间的关系,并演示如何在UI中组织这些关系。

提示

要了解XPO中的持久对象之间的关系,请参阅“代码和UI中的持久对象之间的关系”主题。

“许多”端是集合属性,在WinForms和ASP.NET应用程序中使用ListPropertyEditor在UI中显示。为了显示“一”面, 相应地在WinForms和ASP.NET应用程序中使用LookupPropertyEditorASPxLookupPropertyEditor。如果ExpandObjectMembersAttribute被施加到与所述参考属性ExpandObjectMembers.Never参数,ObjectPropertyEditor代替。每个实体集合都有一个单独的动作集,具体取决于集合类型。

本主题包括以下部分。

一对多(非汇总)

一个部门中可以包含许多联系人时,部门与联系人之间的关系说明了一对多的类型。在此示例中,Department实体包含一个子ContactsCollection集合,并且是其一对多关系的“一侧”。

NonAggregatedOneToManyObject_Win

NonAggregatedOneToManyObject_Web

显示ContactsCollection的列表视图伴随有一个New Action。该操作允许最终用户将新的联系人实体添加到现有部门之一(包括当前实体)中。此外,还可以使用“链接”和“取消链接”操作,并允许您从另一个集合中添加和删​​除对Contact对象的引用。

以下代码演示了如何实现这种类型的关系。

[DefaultClassOptions]
public class Contact {
    [Browsable(false)]
    public Int32 ContactId { get; protected set; }
    public String FirstName { get; set; }
    public String LastName { get; set; }
    public virtual Department Department { get; set; }
}
[DefaultClassOptions]
public class Department {
    [Browsable(false)]
    public Int32 DepartmentId { get; protected set; }
    public String Name { get; set; }
    public Department() {
        ContactsCollection = new List<Contact>();
    }
    public virtual IList<Contact> ContactsCollection { get; set; }
}

一对多(汇总)

假设一个联系人有一个便笺集合,这些便笺和它们的父联系人一起汇总。在这种情况下,Note实体声明与Contact实体的一对多关系的“一个”聚合面。

注意

在Entity Framework中,聚合机制不支持级联删除,但是,您可以按照“对聚合实体的级联删除”部分中所述的那样来实现此功能。

AggregatedOneToManyObject_Win

AggregatedOneToManyObject_Web

显示NotesCollection的列表视图伴随有New Action。此操作允许最终用户添加新的Note实体。请注意,在这种情况下,新Note的Contact属性将自动设置为当前Contact。

如果集合使用AggregatedAttribute装饰,则该集合将被聚合。以下代码演示了如何实现这种类型的关系。

[DefaultClassOptions]
public class Contact {
    [Browsable(false)]
    public Int32 ContactId { get; protected set; }
    public String FirstName { get; set; }
    public String LastName { get; set; }
    public Contact() {
        NotesCollection = new List<Note>();
    }
    [DevExpress.ExpressApp.DC.Aggregated]
    public virtual IList<Note> NotesCollection { get; set; }
}
[DefaultClassOptions]
public class Note {
    [Browsable(false)]
    public Int32 NoteId { get; protected set; }
    public String Text { get; set; }        
    public virtual Contact Contact { get; set; }
}

多对多

例如,每个联系人可以具有一组任务,并且每个任务可以分配给多个联系人。因此,ContactTask实体之间的关系称为“多对多”。

NonAggregatedManyToManyObject_Win

NonAggregatedManyToManyObject_Web

显示TasksCollection的列表视图附带链接操作。此操作允许最终用户添加对现有Task对象的引用。在新的行动不应用到这个集合,由于许多对许多关系的独特概念性质。但是,您可以在“链接操作”的弹出窗口中创建一个新的任务

取消链接操作也提供了TasksCollection。此操作允许最终用户从集合中删除对Task对象的引用。

以下代码演示了如何实现这种类型的关系。

[DefaultClassOptions]
public class Contact {
    [Browsable(false)]
    public Int32 ContactId { get; protected set; }
    public String FirstName { get; set; }
    public String LastName { get; set; }
    public Contact() {
        TasksCollection = new List<Task>(); 
    }
    public virtual IList<Task> TasksCollection { get; set; }
}
[DefaultClassOptions]
public class Task {
    [Browsable(false)]
    public Int32 TaskId { get; protected set; }
    public String Subject { get; set; }
    public DateTime DueDate { get; set; }    
    public Task() {
        ContactsCollection = new List<Contact>();
    }
    public virtual IList<Contact> ContactsCollection { get; set; }
}

一对一

如果每个联系人只能有一个唯一的地址,并且一个地址不能分配给多个联系人,则此关系为一对一。

地址_Win

地址_网页

这种关系没有提供收集方面的信息。请注意,在这种情况下,新Address对象的Contact属性将自动设置为当前Contact。

以下代码演示了如何实现这种类型的关系。在这种关系类型中,重要的是将父实体的主键显式声明为主键,并在相关实体中声明外键。

[DefaultClassOptions]
public class Contact {
    [Browsable(false)]
    public Int32 ContactId { get; protected set; }
    public String FirstName { get; set; }
    public String LastName { get; set; }
    public Contact() { }
    public virtual Address Address { get; set; }
}
[DefaultClassOptions]
public class Address {
    [Browsable(false)] 
    [Key, ForeignKey(nameof(Contact))]
    public Int32 ContactId { get; protected set; }
    public String FullAddress { get; set; }
    public String ZipPostal { get; set; }
    public virtual Contact Contact { get; set; }
}

级联删除实体

在使用Entity Framework的应用程序中,聚合不使用嵌套的IObjectSpace,因此级联删除机制没有与此属性一起组织。要实现此机制,请在模型构建器的OnModelCreating(DbModelBuilder)方法中强制实施此机制。使用Fluent API调用WillCascadeOnDelete(true)方法,如下所示。

public class MySolutionDbContext : DbContext {
    //...
    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        //...
        modelBuilder.Entity<Contact>()
            .HasMany(r => r.AggregatedOneToManyCollection)
            .WithRequired(x => x.Contact)
            .WillCascadeOnDelete();
    }
}

另外,您可以使用[System.ComponentModel.DataAnnotations.Required]属性,如下所示。

[DefaultClassOptions]
public class Contact {
    //...
    [DevExpress.ExpressApp.DC.Aggregated]
    public virtual IList<Note> NotesCollection { get; set; }
}
[DefaultClassOptions]
public class Note {
    //...
    [System.ComponentModel.DataAnnotations.Required]
    public virtual Contact Contact { get; set; }
}
相关文章

转载保留此链接,注明出处