在c#和entity framework中,如何确保现有记录不能被更改,新记录只能在检查通过后才能添加?
In c# and entity framework how can I ensure that existing records cannot be changed and new records can only be added after passing checks?
我想在 c# 6 和 entity framework 6 中创建一个简单的总帐应用程序,但我想我正在为正确的设计而苦苦挣扎。
从我(简化)的角度来看,总账是交易的集合,以后可以用来编译相关的data/reports。
我对交易的要求是:
- 一旦交易被added/posted到总账,为了确保完整的审计追踪,交易不能被更改或删除。
- 只有当相应的日期在特定(会计)期间时,才能添加新交易。其他支票(例如,如果贷方和借方金额匹配)也将被应用。
- 现有交易(即较早发布的交易)也应该可用,但加载后它们不能再通过上述检查(例如它们可能来自较早的会计期间)。
这是我到目前为止的想法:
public class GeneralLedger
{
public int GeneralLedgerId { get; set; }
public DateTime FiscalPeriodStartDate { get; set; }
public DateTime FiscalPeriodEndDate { get; set; }
private ICollection<GeneralLedgerTransaction> _transactions;
public ICollection<GeneralLedgerTransaction> Transactions {
get
{
if (this._transactions != null) {
return this._transactions.ToList().AsReadOnly();
}
else
{
return null;
}
}
}
public void AddTransaction(GeneralLedgerTransaction trx)
{
if (trx.PostingDate < this.FiscalPeriodStartDate || trx.PostingDate > this.FiscalPeriodEndDate)
{
throw new ArgumentOutOfRangeException("invalid booking date");
}
else
{
this._transactions.Add(trx);
}
}
}
public class GeneralLedgerTransaction
{
public int GeneralLedgerTransactionId { get; set; }
public DateTime PostingDate { get; set; }
public virtual ICollection<GeneralLedgerTransactionLine> GeneralLedgerTransactionLines { get; set; }
}
public class GeneralLedgerTransactionLine
{
public int GeneralLedgerTransactionLineId { get; set; }
public int FinancialAccountId { get; set; }
public virtual FinancialAccount FinancialAccount { get; set; }
public int GeneralLedgerTransactionTypeId { get; set; }
public virtual GeneralLedgerTransactionType GeneralLedgerTransactionType { get; set; }
public decimal Amount { get; set; }
}
public class FinancialAccount
{
public int FinancialAccountId { get; set; }
public string Name { get; set; }
}
public class GeneralLedgerTransactionType
{
public int GeneralLedgerTransactionTypeId { get; set; }
public string Name { get; set; }
}
public class MyDbContext : DbContext
{
public DbSet<GeneralLedger> GeneralLedgers { get; set; }
public DbSet<GeneralLedgerTransaction> GeneralLedgerTransactions { get; set; }
public DbSet<GeneralLedgerTransactionLine> GeneralLedgerTransactionLines { get; set; }
public DbSet<FinancialAccount> FinancialAccounts { get; set; }
public DbSet<GeneralLedgerTransactionType> GeneralLedgerTransactionTypes { get; set; }
}
现在这在没有现有交易可以被删除或更改方面运作良好,因为 Transaction
属性 returns 一个 ReadOnly
-list 和每个新的根据日期期间规则检查添加的交易。而且我还可以看到记录已保存到数据库中。到目前为止一切顺利,我目前唯一缺少的是现有记录未加载到 _transactions
.
如何在不从域 class 调用 entity framework 的情况下使现有交易在 _transactions
中可用?或者是否有更好的方法(即更好的设计)来解决这个问题?
经过进一步调查,我了解到我可以通过以下方式实现我正在寻找的目标:
- 将
_transactions
从 private
更改为 protected virtual
- 将
modelBuilder.Configurations.Add(new GeneralLedger.GeneralLedgerTransactionsMapper());
添加到 OnModelCreating
- 正在创建以下配置-class:
.
public class GeneralLedgerTransactionsMapper : EntityTypeConfiguration<GeneralLedger>
{
public GeneralLedgerTransactionsMapper()
{
HasMany(s => s._transactions);
}
}
我想在 c# 6 和 entity framework 6 中创建一个简单的总帐应用程序,但我想我正在为正确的设计而苦苦挣扎。
从我(简化)的角度来看,总账是交易的集合,以后可以用来编译相关的data/reports。
我对交易的要求是:
- 一旦交易被added/posted到总账,为了确保完整的审计追踪,交易不能被更改或删除。
- 只有当相应的日期在特定(会计)期间时,才能添加新交易。其他支票(例如,如果贷方和借方金额匹配)也将被应用。
- 现有交易(即较早发布的交易)也应该可用,但加载后它们不能再通过上述检查(例如它们可能来自较早的会计期间)。
这是我到目前为止的想法:
public class GeneralLedger
{
public int GeneralLedgerId { get; set; }
public DateTime FiscalPeriodStartDate { get; set; }
public DateTime FiscalPeriodEndDate { get; set; }
private ICollection<GeneralLedgerTransaction> _transactions;
public ICollection<GeneralLedgerTransaction> Transactions {
get
{
if (this._transactions != null) {
return this._transactions.ToList().AsReadOnly();
}
else
{
return null;
}
}
}
public void AddTransaction(GeneralLedgerTransaction trx)
{
if (trx.PostingDate < this.FiscalPeriodStartDate || trx.PostingDate > this.FiscalPeriodEndDate)
{
throw new ArgumentOutOfRangeException("invalid booking date");
}
else
{
this._transactions.Add(trx);
}
}
}
public class GeneralLedgerTransaction
{
public int GeneralLedgerTransactionId { get; set; }
public DateTime PostingDate { get; set; }
public virtual ICollection<GeneralLedgerTransactionLine> GeneralLedgerTransactionLines { get; set; }
}
public class GeneralLedgerTransactionLine
{
public int GeneralLedgerTransactionLineId { get; set; }
public int FinancialAccountId { get; set; }
public virtual FinancialAccount FinancialAccount { get; set; }
public int GeneralLedgerTransactionTypeId { get; set; }
public virtual GeneralLedgerTransactionType GeneralLedgerTransactionType { get; set; }
public decimal Amount { get; set; }
}
public class FinancialAccount
{
public int FinancialAccountId { get; set; }
public string Name { get; set; }
}
public class GeneralLedgerTransactionType
{
public int GeneralLedgerTransactionTypeId { get; set; }
public string Name { get; set; }
}
public class MyDbContext : DbContext
{
public DbSet<GeneralLedger> GeneralLedgers { get; set; }
public DbSet<GeneralLedgerTransaction> GeneralLedgerTransactions { get; set; }
public DbSet<GeneralLedgerTransactionLine> GeneralLedgerTransactionLines { get; set; }
public DbSet<FinancialAccount> FinancialAccounts { get; set; }
public DbSet<GeneralLedgerTransactionType> GeneralLedgerTransactionTypes { get; set; }
}
现在这在没有现有交易可以被删除或更改方面运作良好,因为 Transaction
属性 returns 一个 ReadOnly
-list 和每个新的根据日期期间规则检查添加的交易。而且我还可以看到记录已保存到数据库中。到目前为止一切顺利,我目前唯一缺少的是现有记录未加载到 _transactions
.
如何在不从域 class 调用 entity framework 的情况下使现有交易在 _transactions
中可用?或者是否有更好的方法(即更好的设计)来解决这个问题?
经过进一步调查,我了解到我可以通过以下方式实现我正在寻找的目标:
- 将
_transactions
从private
更改为protected virtual
- 将
modelBuilder.Configurations.Add(new GeneralLedger.GeneralLedgerTransactionsMapper());
添加到OnModelCreating
- 正在创建以下配置-class:
.
public class GeneralLedgerTransactionsMapper : EntityTypeConfiguration<GeneralLedger>
{
public GeneralLedgerTransactionsMapper()
{
HasMany(s => s._transactions);
}
}