So I've done a good job separating the DAL from the BLL. I use repositories for each aggregate root. The issue I'm having is database concurrency with IDs in the domain.
I don't want to use the surrogate key in the domain layer (e.g. GUID). So the aggregate root I have now is a Journal and that Journal has a list of transactions. The first table is Journals and the second table is Transactions that map back to the first table.
It looks like this:
Journals
+----------------------------------------+
| ID | JournalID | LastTransactionID |
+----------------------------------------+
|{a-as}| 1 | 8 |
|{ase1}| 2 | 1 |
|......|...........|.....................|
|{1sas}| 45 | 4 |
+----------------------------------------+
Transactions
+----------------------------------------------------+
| ID | JournalID | TransactionID | Account | Amount|
+----------------------------------------------------+
|{a2ba}| 1 | 1 | xxxxxxx | 10.20 |
|{2a4a}| 1 | 2 | xxxxxxx | 1.10 |
|{20s9}| 2 | 1 | xxxxxxx | 93.12 |
|......|...........|...............|.........|.......|
|{9eka}| 45 | 4 | xxxxxxx | 291.10|
+----------------------------------------------------+
So I use the LastTransactionID from the Journals column to figure out how to assign a domain ID (TransactionID) to new transactions. The issue I'm having is if more than one desktop app instance is accessing the same Journal then the LastTransactionID could be stale and causes issues with trying to insert new transactions.
My domain classes look like:
class Journal
{
public int JournalID { get; private set; }
public int LastTransactionID { get; private set; }
public IEnumerable<Transaction> Transactions { get; private set; }
public Journal(int journalID, int lastTransactionID, IEnumerable<Transaction> transactions)
{
// do work......
}
}
class Transaction
{
public int JournalID { get; private set; }
public int TransactionID { get; private set; }
public Account Account { get; private set; }
public Money Amount { get; private set; }
public Journal(int journalID, int transactionID, Account account, Money amount)
{
// do work......
}
}
I'm using EF and have this encapsulated in my repository. Maybe I'm using a poor database design?