I have two databases: one for a warehouse, second for the office (The db design is out of the scope of this question). There are MANY cross-database funtions. One of those functions is IsPurchaseOrderClosed
. I need data from TWO databases to determine this.
I was trying to build a DAL using UnitOfWork and Repository pattern (I always created UoW and Repository classes and interfaces. I knew DbContext already implements both patterns.. but I wanted to abstract EF layer). Anyway.. in this case, I decided to remove both elements and stick with DbContext and Service layer.
Here's my solution:
public class WarehouseContext : DbContext
{
public WarehouseContext()
: base("name=WarehouseContext")
{
this.Configuration.LazyLoadingEnabled = false;
}
public virtual DbSet<PurchaseOrder> PurchaseOrders { get; set; }
public virtual DbSet<Inventory> Inventories { get; set; }
public virtual DbSet<Orders> Orders { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<WarehouseContext>(null);
base.OnModelCreating(modelBuilder);
}
}
public class OfficeContext : DbContext
{
public OfficeContext()
: base("name=OfficeContext")
{
this.Configuration.LazyLoadingEnabled = false;
}
public virtual DbSet<Invoice> Invoices { get; set; }
public virtual DbSet<Supplier> Suppliers { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<OfficeContext>(null);
base.OnModelCreating(modelBuilder);
}
}
public class ContextFactory : IContextFactory
{
public WarehouseContext CreateWarehouseContext()
{
return new WarehouseContext();
}
public OfficeContext CreateOfficeContext()
{
return new OfficeContext();
}
}
public class PurchaseOrderService
{
IContextFactory ContextFactory { get; set; }
public PurchaseOrderService(IContextFactory contextFactory)
{
ContextFactory = contextFactory;
}
//Service method, that interact with two databases:
public bool IsPurchaseOrderClosed(int poId)
{
bool toReturn = false;
using(var WarehouseContext = ContextFactory.CreateWarehouseContext())
{
PurchaseOrder purchaseOrder = WarehouseContext.PurchaseOrders.Find(poId);
if (!purchaseOrder.IsClosed)
{
using(var OfficeContext = ContextFactory.CreateOfficeContext())
{
int invoiceId = purchaseOrder.InvoiceId;
Invoice invoice = OfficeContext.Invoices.Find(invoiceId);
if (invoice.WasSent)
{
toReturn = true;
}
}
}
else
{
toReturn = true;
}
}
return toReturn;
}
}
I have two questions:
Is this solution good? (By good I mean, does it meet every good-practice advice, SOLID principles etc)
In
IsPurchaseOrderClosed
method I get tables usingOfficeContext.Set<Invoice>().Find(invoiceId);
to get particular Invoice object from the database. Isn't it too.. complex/not readable? I was thinking how can I make it more simple? Should I create some kinda generic Service, with all basic/CRUD methods?I have also third question: Currently
ContextFactory
is the part of.Data
subproject (where my Contexts and Entities resides). Do you think it should be in.Business
layer, which is the Service Layer (I prefer using Business or Logic words - because many people confuse it with WCF or Windows Service)?
SaveChanges
if you didn't change anything? Have you posted edited code? \$\endgroup\$