Reputation: 538
I am working on a WCF Service application which is using EF for data access. All my EF models under DataLayer. I have created following factory method under data layer
namespace TRA.Services.DataAccessLayer
{
public static class DataObjectFactory
{
public static TRAEntities CreateTRAContext()
{
return new TRAEntities();
}
}
}
In business layer I am trying to use following code :
using (var context = DataObjectFactory.CreateTRAContext())
{
var objClients = from r in context.TRAEmployee
orderby r.id
select r;
}
It gives me following error : "The type 'DBContext' is defined in an assembly that is not referenced. You must add a reference to assembly 'EntityFramework, Version=6.0.0.0,......"
Since I am using this code in business layer I dont want to add reference to EntityFramework.
Is there any way to handle this scenario?
Upvotes: 0
Views: 217
Reputation: 2664
The problem here is more of a conceptual nature.
Instead of exposing a method that returns an instance of TRAEntities
, you should create an Accessor
that returns the employees list to the bsuness logic layer, such as:
IEnumerable<Employee> GetEmployees()
{
IEnumerable<Employee> employees;
using (var context = DataObjectFactory.CreateTRAContext())
{
employees = from r in context.TRAEmployee
orderby r.id
select r;
}
return employees;
}
Additionally, if abstraction between layers is important, implement a separate Employee entity for moving the data out of the data access layer.
Upvotes: 0
Reputation: 151720
Every type in the inheritance tree of types you publicly expose from a class member in an assembly (public static TRAEntities
where TRAEntities : DbContext
) must be known to referencing assemblies if they want to use that member.
So because you're exposing and accessing DataObjectFactory.CreateTRAContext()
from your business layer, and the type returned from that method inherits from Entity Framework's DbContext
, your business layer needs a reference to Entity Framework.
You can solve this problem by introducing a layer of indirection, in this case generally done through some repository layer. This also makes your business layer testable without having to mock Entity Framework.
So instead of pulling in the DbContext
from your data layer and accessing its DbSet<T>
members, you expose repositories which in turn expose the entities you want to access:
public interface IRepository<T>
{
IQueryable<T> Entries();
}
The implementation of this repository is internal to the data layer, and wraps a DbSet<T> DbContext.Set<T>
.
Upvotes: 1