在多租户应用程序场景中,同一模型是否可能具有不同的属性?

时间:2019-03-24 08:57:46

标签: c# entity-framework multi-tenant core

我必须设计一个多租户应用程序,我需要为同一模型中的每个租户有一个自定义字段。

客户1需要使用一些自定义字段,客户2需要管理同一表中的其他字段,依此类推。

这是一个示例: 同一张表(票证)具有一个公共(基本)字段列表,那么每个租户在模型中都应该有他的其他列:

我想首先实现EFCode。NetCore Web应用程序。

namespace Models.Base
{
    public class TicketBase
    {
        public int Id { get; set; }
        public string Description { get; set; }
        public Datetime CreationDate { get; set; } 
    }
}

租户1

namespace Models.Tenant1
{
    public class Ticket : TicketBase
    {

        public string CustomerName { get; set; }
        public Datetime DateCustomerCall { get; set; } 
    }
}

Tenant 2

namespace Models.Tenant2
{
    public class Ticket : TicketBase
    {

        public string AnotherDescription { get; set; }
        public Datetime AnotherDate { get; set; } 
    }
}

以这种方式设计模型是否正确,或者对于这个非常常见的问题有不同的方法?

1 个答案:

答案 0 :(得分:1)

IMHO,在SaaS中,具有单一代码库和灵活的多租户配置/扩展是成功的关键。

要为每个租户启用自定义字段,业务模型将必须具有固定的设置基本字段。自定义字段必须按entityid和ten​​antid存储在单独的表中。

您的表格可能如下所示。此模型是首选模型,因此拥有通用扩展表将导致可伸缩性降低,并且随着使用量的增加,很快就会被数据量填充。

门票

TicketExtn(扩展表,包含按承租人和实体的自定义字段)

TicketExtn表将包含类似字段

TicketId TenantId FieldId FieldValue FieldDataType 等等 当我们尝试获取Ticket实体的数据时,我们还将从TicketExtn表中获取数据并在模型中设置字段。

BaseModel如下所示

public class ExtendedField
{
    public Guid Id { get; set; }
    public string FieldName { get; set; }
    public Guid DataTypeId { get; set; }
    /// <summary>
    /// Can also be a typed class, this is just for reference
    /// </summary>
    /// <value>The field value.</value>
    public string FieldValue { get; set; }
    /// <summary>
    /// Incase of using string for fieldvalue, the string to format the value as per the required datatype 
    /// will be provided here.
    /// </summary>
    /// <value>The field value format string.</value>
    public string FieldValueFormatString { get; set; }
}

public class BaseModel
{
    Dictionary<string, ExtendedField> ExtendedRows { get; set; }
}

public class Ticket : BaseModel
{
    public int Id { get; set; }
    public string Description { get; set; }
    public DateTime CreationDate { get; set; }
}

在您的服务层中,将存在逻辑来填充这些扩展的行。最好有一种逻辑来填充通用的扩展行,这样对于任何数量的实体,这种逻辑都可以重复使用。

HTH