Entity framework 在关系数据库的一个表上,哪一个应该是首选的1:1,0或空字段?

Entity framework 在关系数据库的一个表上,哪一个应该是首选的1:1,0或空字段?,entity-framework,database-design,orm,ef-code-first,relational-database,Entity Framework,Database Design,Orm,Ef Code First,Relational Database,我首先使用Azure Sql和实体框架代码 我有事务表。有4种类型,分别是买入/卖出,取款,存款和费用 例如,对于存款交易,我需要DepositCode,但对于其他交易,此列将为空。另外,我需要购买/出售的ItemPrice和itemamuty,但对于其他类型,它将为空 示例事务表 public class Transaction { public long Id { get; set; } public decimal Amount { get; se

我首先使用Azure Sql和实体框架代码

我有
事务
表。有4种类型,分别是
买入/卖出
取款
存款
费用

例如,对于存款交易,我需要
DepositCode
,但对于其他交易,此列将为空。另外,我需要购买/出售的
ItemPrice
itemamuty
,但对于其他类型,它将为空

示例
事务

 public class Transaction
    {
        public long Id { get; set; }
        public decimal Amount { get; set; }
        public int Type { get; set; }
        public string DepositCode { get; set; }
        public decimal? ItemPrice { get; set; }
        public decimal? ItemAmount { get; set; }
        public string WithdrawalIban { get; set; }
    }

公共类事务
{
公共长Id{get;set;}
公共十进制数{get;set;}
公共int类型{get;set;}
公共存款交易{get;set;}
公开取款交易买卖交易{get;set;}
公共取款交易取款交易{get;set;}
}
公共类存款交易
{
公共长Id{get;set;}
公共事务{get;set;}
公共字符串存储代码{get;set;}
}
公共类撤销交易
{
公共长Id{get;set;}
公共事务{get;set;}
公共字符串{get;set;}
}
公共类买卖交易
{
公共长Id{get;set;}
公共事务{get;set;}
公共十进制ItemPrice{get;set;}
公共十进制项金额{get;set;}
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity()
.HasRequired(wt=>wt.Transaction)
.带可选(tr=>tr.取款交易);
modelBuilder.Entity()
.HasRequired(db=>db.Transaction)
.with可选(tr=>tr.DepositTransaction);
modelBuilder.Entity()
.HasRequired(bs=>bs.Transaction)
.with可选(tr=>tr.BuySellTransaction);
}

应该首选哪一个?

如果可能,我更喜欢可为空的字段,这是表/类层次结构映射中的实现。使用这种方法,EF将所有事务对象存储在一个表中,并使用鉴别器列为您管理类型加载。也就是说,我将按如下方式重构您的模型:

public abstract class Transaction
{
    public long Id { get; set; }
    public DateTime TransactionDate { get; set; }
}


public class DepositTransaction : Transaction
{
    public string DepositCode { get; set; }
}


public class WithdrawalTransaction : Transaction
{
    public string WithdrawalIban { get; set; }
}


public class BuySellTransaction : Transaction
{
    public decimal ItemPrice { get; set; }
    public decimal ItemAmount { get; set; }
}

你实际上只有三笔交易:买入/卖出、存款/取款、手续费。买入和卖出的区别在于,买入的金额为正,卖出的金额为负。存款和取款也是如此

create table Transactions(
    ID         bigint identity primary key,
    XType      char( 1 ) not null, -- 'B': buy/sell, 'D': dep/with, 'F': fee
    Amount     money not null,
    constraint CK_Transaction_Type check( XType in( 'B', 'D', 'F' ),
    constraint UQ_Transaction_Type unique( ID, XType )
);
其他表(或子表,如果您想这样认为的话)如下所示:

create table BuySellTrans(
    TransID    bigint not null,
    TransType  char( 1 ) not null,
    ...,   -- other info regarding purchase or sale
    constraint CK_BuySellTrans_BuySellType check( TransType = 'B' )
    constraint FK_BuySellTrans_Trans foreign key( TransID, TransType )
        references Transactions( ID, XType )
);

至于代码,最好的方法可能是拥有一个抽象的超类事务,其中包含BuySell、DepositRetraction和Fee子类。我还将提供一些方便的意见命名,巧合的是,买卖,存款和费用。这些视图将提供具有适当子表的事务表的联接数据集。视图上的触发器(您的系统允许)将大大简化应用程序代码,因为每个子类只通过视图进行查询和操作。代码甚至不需要知道数据库中的物理布局。

如果我想向用户显示所有事务,查询将是什么?您能举个例子吗?对于这种情况,您可以使用投影创建所需的输出,甚至可以在数据库中创建一个视图,并将其映射到一个只读实体以用于报告或列表目的。您还可以将事务类更改为非抽象类。对基类发出的查询将从与基类型和派生类型对应的数据库表中检索记录。感谢我同时使用tph和tpt(用于非常罕见的数据)。创建
constraint UQ\u Transaction\u Type unique(ID,XType)
,目的是什么,创建ID
标识主键
还不够吗?是的,在事务中,主键是使每一行唯一所需的全部。但是,我们还需要类型级别的唯一性来强制不同类型表的引用完整性。这不仅在事务中,而且在不同类型的各种子表中强制唯一性。例如,输入ID为1001的事务条目。该表中不能有另一个ID 1001。但1001可以输入BuySellTrans、Dep取款或费用表。不好的。添加的唯一约束限制了表可以包含ID1001——具有相同类型的表。
create table BuySellTrans(
    TransID    bigint not null,
    TransType  char( 1 ) not null,
    ...,   -- other info regarding purchase or sale
    constraint CK_BuySellTrans_BuySellType check( TransType = 'B' )
    constraint FK_BuySellTrans_Trans foreign key( TransID, TransType )
        references Transactions( ID, XType )
);