Seeding data in custom Db Initializer won't work / EF, Code First - entity-framework

I am trying to seed some data using custom database initializers, but can't get it to work. I tried adding some configurations to appConfig file but that didn't work either.
It is a WPF application and I don't want to reference my EntityLibrary. I want to seed data using context's constructor. What's wrong with it?
Edit: The problem is no data gets populated. When debugging I see the context's constructor SetInitiazlier function is called but overridden Seed method never gets called, in fact debugger never enters the Seed method.
At the same time XAML parser gives an error complaining about the TContext type paramter of
DropCreateDatabaseIfModelChanges. I can't give the exact error since I don't have the code at home.
This is my custom initializer:
public class DbInitializer : DropCreateDatabaseIfModelChanges<DemirbaşContext>
{
protected override void Seed(DemirbaşContext context)
{
Kullanıcı kullanıcı = new Kullanıcı
{
Ad = "Mert",
Soyad = "Mert",
KullanıcıAdı = "admin",
Şifre = "password",
Email = "mert#mert.com"
};
context.Kullanıcılar.Add(kullanıcı);
context.SaveChanges();
base.Seed(context);
}
}
This is my context constructor:
public DemirbaşContext():base("Demirbaş")
{
Database.SetInitializer<DemirbaşContext>(new DbInitializer());
}
EDIT 1: Here is my current code, but still it does not seed the data. Can you see what's wrong?
Initializer:
public class DbInitializer : DropCreateDatabaseIfModelChanges<DemirbaşContext>
{
protected override void Seed(DemirbaşContext context)
{
Kullanıcı kullanıcı = new Kullanıcı
{
Ad = "Mert",
Soyad = "Mert",
KullanıcıAdı = "admin",
Şifre = "password",
Email = "mert#mert.com"
};
context.Kullanıcılar.Add(kullanıcı);
context.SaveChanges();
}
}
Application Startup:
public partial class App : Application
{
public App()
{
// Seed data, remove after getting seeding in custom db initiazlier to work
DemirbaşContext context = new DemirbaşContext();
DbInitializer initializer = new DbInitializer();
Database.SetInitializer<DemirbaşContext>(initializer);
context.Database.Initialize(false);
}
}

Move your initialization code to your application startup. It doesn't belong to context's constructor and force initialization manually:
Database.SetInitializer<DemirbaşContext>(new DbInitializer());
context.Database.Initialize(false);

Related

Concrete type instance registration in Autofac fails to resolve in a nested scope when using AnyConcreteTypeNotAlreadyRegisteredSource source

I have an Autofac container that uses "AnyConcreteTypeNotAlreadyRegisteredSource" to allow resolution of any concrete type without explicit need to register it. If I register a singleton instance of a concrete type using the RegisterInstance method, there are no issues with the resolution. However, if I create a child lifetime scope and do the same concrete type singleton instance registration, the child lifetime scope is not able to resolve the type anymore. It throws the following exception:
Autofac.Core.Activators.Reflection.NoConstructorsFoundException: 'No accessible constructors were found for the type 'AutofacTests.IssueTests+Manager'.'
Why is it even trying to instantiate the object when I have a singleton instance of that type registered already? It seems like this problem only comes when I try to resolve a concrete type instead of an interface.
Here is the test code that demonstrates the problem (The test method name and comments show what works and what does not):
using Autofac;
using Autofac.Features.ResolveAnything;
namespace AutofacTests
{
[TestClass]
public class IssueTests
{
private interface IPerson
{
}
private class Employee : IPerson
{
public Employee()
{
}
}
private class Manager : Employee
{
internal Manager(IPerson worker)
{
string s = "";
}
}
[TestMethod]
public void Resolution_ThatWorks()
{
ContainerBuilder builder = new ContainerBuilder();
var mgr = new Manager(null);
builder.RegisterInstance<IPerson>(mgr);
builder.RegisterInstance<Manager>(mgr);
using (var container = builder.Build())
{
var person = container.Resolve<Manager>();
Assert.IsNotNull(person, "Employee could not be resolved!");
}
}
[TestMethod]
public void ResolutionWithAnyTypeSource_ThatWorks()
{
ContainerBuilder builder = new ContainerBuilder();
// NOTE: This source registration does not impact the concrete type resolution when no child lifetime scope is involved.
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());
var mgr = new Manager(null);
builder.RegisterInstance<IPerson>(mgr);
builder.RegisterInstance<Manager>(mgr);
using (var container = builder.Build())
{
var person = container.Resolve<Manager>();
Assert.IsNotNull(person, "Employee could not be resolved!");
}
}
[TestMethod]
public void NestedResolution_ThatWorks()
{
ContainerBuilder builder = new ContainerBuilder();
using (var container = builder.Build())
{
void RegisterNestedServices(ContainerBuilder builder)
{
var mgr = new Manager(null);
builder.RegisterInstance<IPerson>(mgr);
builder.RegisterInstance<Manager>(mgr);
}
using (var childContainer = container.BeginLifetimeScope(RegisterNestedServices))
{
var person = childContainer.Resolve<Manager>();
Assert.IsNotNull(person, "Employee could not be resolved!");
}
}
}
[TestMethod]
public void NestedResolutionWithAnyTypeSource_ThatFails()
{
ContainerBuilder builder = new ContainerBuilder();
// NOTE: This source registration causes the resolution of a concrete type to fail in a child lifetime scope.
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());
using (var container = builder.Build())
{
void RegisterNestedServices(ContainerBuilder builder)
{
var mgr = new Manager(null);
builder.RegisterInstance<IPerson>(mgr);
builder.RegisterInstance<Manager>(mgr);
}
using (var childContainer = container.BeginLifetimeScope(RegisterNestedServices))
{
// Works
var person = childContainer.Resolve<IPerson>();
Assert.IsNotNull(person, "Person could not be resolved!");
// *** Fails ***
var emp = childContainer.Resolve<Manager>();
Assert.IsNotNull(emp, "Employee could not be resolved!");
}
}
}
}
}
Anyone has any idea what am I doing wrong or how to make this work in the child lifetime scopes?
Thanks.
It appears you're hitting this known issue where AnyConcreteTypeNotAlreadyRegisteredSource (ACTNARS) doesn't properly look at new registrations in child scopes.
At the time of this writing there is not a fix for it, but we'd love a PR to get it fixed. It's been open for a while now.

How to mock Entity Framework in a N-Layer Architecture

I have a N-Layer application with Entity Framework (Code-First approach). Now I want to automatize some tests. I am using Moq framework. I am finding some problem about writing the tests. Perhaps my architecture is wrong? With wrong, I mean that I wrote components that are not well isolated and so they are not testable. I do not really like this... Or perhaps, I simply cannot use correctly moq framework.
I let you see my architecture:
At every level I inject my context in the constructor of the class.
The Facade:
public class PublicAreaFacade : IPublicAreaFacade, IDisposable
{
private UnitOfWork _unitOfWork;
public PublicAreaFacade(IDataContext context)
{
_unitOfWork = new UnitOfWork(context);
}
}
The BLL:
public abstract class BaseManager
{
protected IDataContext Context;
public BaseManager(IDataContext context)
{
this.Context = context;
}
}
The Repository:
public class Repository<TEntity>
where TEntity : class
{
internal PublicAreaContext _context;
internal DbSet<TEntity> _dbSet;
public Repository(IDataContext context)
{
this._context = context as PublicAreaContext;
}
}
IDataContext is an interface that is implemented by my DbContext:
public partial class PublicAreaContext : DbContext, IDataContext
Now, how I mock EF and how I write the tests:
[TestInitialize]
public void Init()
{
this._mockContext = ContextHelper.CreateCompleteContext();
}
Where ContextHelper.CreateCompleteContext() is:
public static PublicAreaContext CreateCompleteContext()
{
//Here I mock my context
var mockContext = new Mock<PublicAreaContext>();
//Here I mock my entities
List<Customer> customers = new List<Customer>()
{
new Customer() { Code = "123455" }, //Customer with no invoice
new Customer() { Code = "123456" }
};
var mockSetCustomer = ContextHelper.SetList(customers);
mockContext.Setup(m => m.Set<Customer>()).Returns(mockSetCustomer);
...
return mockContext.Object;
}
And here how I write my test:
[TestMethod]
public void Success()
{
#region Arrange
PrepareEasyPayPaymentRequest request = new PrepareEasyPayPaymentRequest();
request.CodiceEasyPay = "128855248542874445877";
request.Servizio = "MyService";
#endregion
#region Act
PublicAreaFacade facade = new PublicAreaFacade(this._mockContext);
PrepareEasyPayPaymentResponse response = facade.PrepareEasyPayPayment(request);
#endregion
#region Assert
Assert.IsTrue(response.Result == it.MC.WebApi.Models.ResponseDTO.ResponseResult.Success);
#endregion
}
Here It seems It works everything correctly!!! And It looks like my architecture is correct. But what if I want to insert/update an Entity? Nothing work anymore! I explain why:
As you can see I pass a *Request object (it is the DTO) to the facade, then in my TOA I generate my entity from the propertiess of the DTO:
private PaymentAttemptTrace CreatePaymentAttemptTraceEntity(string customerCode, int idInvoice, DateTime paymentDate)
{
PaymentAttemptTrace trace = new PaymentAttemptTrace();
trace.customerCode = customerCode;
trace.InvoiceId = idInvoice;
trace.PaymentDate = paymentDate;
return trace;
}
PaymentAttemptTrace is the Entity I will inserto to Entity Framework.. It is not mocked and I cannot inject it. So even if I pass my mocked context (IDataContext), when I try to insert an Entity that is not mocked my test fails!
Here that doubt about I have a wrong architecture has raised!
So, what's wrong? The architecture or the way I use moq?
Thank you for help
UPDATE
Here how I test my code.. For example, I want to test the trace of a payment..
Here the test:
[TestMethod]
public void NoPaymentDate()
{
TracePaymentAttemptRequest request = new TracePaymentAttemptRequest();
request.AliasTerminale = "MyTerminal";
//...
//I create my request object
//You can see how I create _mockContext above
PublicAreaFacade facade = new PublicAreaFacade(this._mockContext);
TracePaymentAttemptResponse response = facade.TracePaymentAttempt(request);
//My asserts
}
Here the facade:
public TracePaymentAttemptResponse TracePaymentAttempt(TracePaymentAttemptRequest request)
{
TracePaymentAttemptResponse response = new TracePaymentAttemptResponse();
try
{
...
_unitOfWork.PaymentsManager.SavePaymentAttemptResult(
easyPay.CustomerCode,
request.CodiceTransazione,
request.EsitoPagamento + " - " + request.DescrizioneEsitoPagamento,
request.Email,
request.AliasTerminale,
request.NumeroContratto,
easyPay.IdInvoice,
request.TotalePagamento,
paymentDate);
_unitOfWork.Commit();
response.Result = ResponseResult.Success;
}
catch (Exception ex)
{
response.Result = ResponseResult.Fail;
response.ResultMessage = ex.Message;
}
return response;
}
Here how I developed the PaymentsManager:
public PaymentAttemptTrace SavePaymentAttemptResult(string customerCode, string transactionCode, ...)
{
//here the problem... PaymentAttemptTrace is the entity of entity framework.. Here i do the NEW of the object.. It should be injected, but I think it would be a wrong solution
PaymentAttemptTrace trace = new PaymentAttemptTrace();
trace.customerCode = customerCode;
trace.InvoiceId = idInvoice;
trace.PaymentDate = paymentDate;
trace.Result = result;
trace.Email = email;
trace.Terminal = terminal;
trace.EasypayCode = transactionCode;
trace.Amount = amount;
trace.creditCardId = idCreditCard;
trace.PaymentMethod = paymentMethod;
Repository<PaymentAttemptTrace> repository = new Repository<PaymentAttemptTrace>(base.Context);
repository.Insert(trace);
return trace;
}
In the end how I wrote the repository:
public class Repository<TEntity>
where TEntity : class
{
internal PublicAreaContext _context;
internal DbSet<TEntity> _dbSet;
public Repository(IDataContext context)
{
//the context is mocked.. Its type is {Castle.Proxies.PublicAreaContextProxy}
this._context = context as PublicAreaContext;
//the entity is not mocked. Its type is {PaymentAttemptTrace} but should be {Castle.Proxies.PaymentAttemptTraceProxy}... so _dbSet result NULL
this._dbSet = this._context.Set<TEntity>();
}
public virtual void Insert(TEntity entity)
{
//_dbSet is NULL so "Object reference not set to an instance of an object" exception is raised
this._dbSet.Add(entity);
}
}
Your architecture looks good, but the implementation is flawed. It is leaking abstraction.
In your diagram the Façade layer depends only on the BLL but when you look at the PublicAreaFacade's constructor you will see that in reality it has a direct dependency to an interface from the Repository layer:
public PublicAreaFacade(IDataContext context)
{
_unitOfWork = new UnitOfWork(context);
}
This should not be. It should only take its direct dependency as input -- the PaymentsManager or -- even better -- an interface of it:
public PublicAreaFacade(IPaymentsManager paymentsManager)
{
...
}
The concequence is that your code becomes way more testable. When you look at your tests now you see that you have to mock the most inner layer of your system (i.e. the IDataContext and even its entity accessors Set<TEntity>) altough you are testing one of the most outer layers of your system (the PublicAreaFacade class).
This is how a unit test for the TracePaymentAttempt method would look like if the PublicAreaFacade only depended on IPaymentsManager:
[TestMethod]
public void CallsPaymentManagerWithRequestDataWhenTracingPaymentAttempts()
{
// Arrange
var pm = new Mock<IPaymentsManager>();
var pa = new PulicAreaFacade(pm.Object);
var payment = new TracePaymentAttemptRequest
{
...
}
// Act
pa.TracePaymentAttempt(payment);
// Assert that we call the correct method of the PaymentsManager with the data from
// the request.
pm.Verify(pm => pm.SavePaymentAttemptResult(
It.IsAny<string>(),
payment.CodiceTransazione,
payment.EsitoPagamento + " - " + payment.DescrizioneEsitoPagamento,
payment.Email,
payment.AliasTerminale,
payment.NumeroContratto,
It.IsAny<int>(),
payment.TotalePagamento,
It.IsAny<DateTime>()))
}
Pass IUnitOfWork into the Facade or BLL layer constructor, whichever one makes calls on the unit of work directly. Then you can setup what the Mock<IUnitOfWork> is returning in your tests. You should not need to pass IDataContext to everything except maybe the repo constructors and the unit of work.
For example, if the Facade has a method PrepareEasyPayPayment that makes a repo call through a UnitOfWork call, setup the mock like this:
// Arrange
var unitOfWork = new Mock<IUnitOfWork>();
unitOfWork.Setup(x => x.PrepareEasyPayPaymentRepoCall(request)).Returns(true);
var paymentFacade = new PaymentFacade(unitOfWork.Object);
// Act
var result = paymentFacade.PrepareEasyPayPayment(request);
Then you've mocked out the data call and can more easily test your code in the Facade.
For the insert testing, you should have a Facade method like CreatePayment which takes a PrepareEasyPayPaymentRequest. Inside that CreatePayment method, it should reference the repo, probably through the unit of work, like
var result = _unitOfWork.CreatePaymentRepoCall(request);
if (result == true)
{
// yes!
}
else
{
// oh no!
}
What you want to mock for unit testing is that this create/insert repo call returns true or false so you can test the code branches after the repo call has completed.
You can also test that the insert call was made as expected, but that's usually not as valuable unless the parameters for that call have a lot of logic involved in building them.
it sounds like you need to change the code a little bit. Newing things introduces hardcoded dependencies and makes them untestable, so try to abstract them away. Maybe you can hide everything to do with EF behind another layer, then all you have to do is mock that particular layer layer and never touch EF.
You can use this open source framework for unit testing which is good to mock entity framework dbcontext
https://effort.codeplex.com/
Try this will help you to mock your data efficiently.

EF: How to enclose context object in a using statement?

Let's say I have the following classes Customer.cs, a context OfficeContext.cs, and a repository OfficeRepository.cs. Knowing that the context use a connection object, so it's advised to enclose it in a using statement:
public List<Customer> GetAllCustomersWithOrders()
{
using(var oContext = new OfficeContext())
{
//Code here....
}
}
My question is what if I want to re-use some of the code already in the repository? For instance, what if I want to display all the customers that ordered products but didn't receive them yet, do I need to duplicate the code?
public List<Customer> GetCustomersNotReceiveProducts()
{
using(var oContext = new OfficeContext())
{
//Re-use GetAllCustomersWithOrders() here???...
}
}
But as you can see, each time access a method, I also open instantiate a new context object. Is there any way to deal with that?
What I do is have my repositories implement IDisposable.
Then have two constructors (one default) that instaniates a new context that holds it as a class level variable. And another constructor that takes a context and uses that internally.
The on the dispose of the class the context is disposed (if the current repository instatiated it).
This removes the context out of the method level and moves it to the class level. My functions keep everything in IQueryable so one function can call another function and perform additional refinements before the database it hit.
Exmaple:
public class MemberRepository : IDisposable
{
OfficeContext db;
bool isExternalDb = false;
public MemberRepository()
{
db = new OfficeContext();
isExternalDb = false;
}
public MemberRepository(OfficeContext db)
{
this.db = db;
isExternalDb = true;
}
public IQueryable<Member> GetAllMembers()
{
var members= db.Members
return members;
}
public IQueryable<Member> GetActiveMembers()
{
var members = GetAllMembers();
var activeMembers = members.Where(m => m.isActive == true);
return activeMembers;
}
public void Dispose()
{
if (isExternalDb == false)
{
db.Dispose();
}
}
}
Then where I use the repository, I do a using at that level:
using(var memberRepository = new MemberRepository())
{
var members = memberRepository.GetActiveMembers();
}

Reuse connection among DbContext instances in unit test

I'm trying to setup some unit tests using EntityFramework 5, SQL Server Compact 4 and Xunit.
I'm using different context instances because I'm testing a ASP MVC app and I need to test the behavior of some update operations over detached entities.
[Fact, AutoRollback]
public void TestConnection()
{
using (var connection = this.GetDbConnection())
{
using (var context = new MyContext(connection, false))
{
// Do database stuff
}
using (var context = new MyContext(connection, false))
{
// Do database stuff
}
}
}
public DbConnection GetDbConnection()
{
string dataSource = "|DataDirectory|\\MyDb.sdf";
var sqlBuilder = new SqlCeConnectionStringBuilder();
sqlBuilder.DataSource = dataSource;
return new SqlCeConnection(sqlBuilder.ToString());
}
This gives me the following error:
System.Data.EntityException : The underlying provider failed on Open.
System.InvalidOperationException : The connection object can not be enlisted in transaction scope.
I know I can't open multiple DbContext instances inside a TransactionScope (that is probably what Xunit does when you put a FallbackAttribute in your method), so that's why I'm creating the connection beforehand.
If I try to open the connection myself, it still does not work:
using (var connection = this.GetDbConnection())
{
connection.Open();
using (var context = new MyContext(connection, false))
{
I get the following exception:
System.ArgumentException : EntityConnection can only be constructed with a closed DbConnection.
Does any one know how to solve that issue?
EDIT
The test classes that deal with the Db extend a "DomainFactsBase" where the database is initialized as the following:
public DomainFactsBase()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyContext>());
using (var context = new MyContext(GetDbConnection(), true))
context.Database.Initialize(false);
}
EDIT
I can sucessfully run tests with autorollback when I create only one context instance. This was accomplished following the instructions in this article. I have a extension method:
public static void OpenConnection(this DbContext context)
{
((IObjectContextAdapter)context).ObjectContext.Connection.Open();
}
And I call it right after creating the context in the tests:
[Fact, AutoRollback]
public void SomeFact()
{
using (var context = new MyContext())
{
context.OpenConnection();
// Do stuff
}
}
That work with no problems. They arise when I try to open the context more than once in the same fact (with AutoRollback enabled), as I examplified in the beginning.
Initialize the database outside of the test. You can do this inside of the test class's constructor.
public MyTestClass()
{
using (var db = new MyContext(GetDbConnection(), true))
{
db.Database.Initialize(false);
}
}

How to manage ObjectContext lifetime correctly in multi-tier application using Entity Framework?

I have seen many examples using Entity Framework in MVC3 applications, they are very simple demos which only have one mvc3 web project with edmx inside it.
So, they can use the best practice for open and close connection by "using" statement:
using(var context = new SchoolEntities())
{
// do some query and return View with result.
}
And, It can use lazy load (navigation properties) inside the "using" statment correctly, because the context is not yet
disposed:
foreach(var item in student.Course)
{
// do something with the navigation property Course
}
All things seems to be perfect until it becomes an n-tier application.
I created DAL, BLL, and a MVC3 UI.
The DAL have edmx inside it, and operator classes like SchoolDA.cs:
public class StudentDA()
{
public Student FindStudent(int studentId)
{
using(var context = new SchoolContext())
{
// do query, return a student object.
}
}
}
Then, in the BLL, if I use:
var student = studentDa.FindStudent(103);
then invoke it's navigation property:
student.Course
I will get an error (of course):
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
So, I have to change StudentDA.cs like this:
public class StudentDA() : IDisposable
{
private SchoolEntites context;
public StudentDA()
{
context = new SchoolEntities();
}
public void Dispose()
{
context.Dispose();
}
public Student FindStudent(int studentId)
{
// do query, return a student object.
}
}
Then, the BLL will change like this:
public Student FindStudent(int id)
{
using(var studentDa = new StudentDA())
{
// this can access navigation properties without error, and close the connection correctly.
return studentDa.FindStudent(id);
}
}
All things seem to be perfect again until it meet Update() method.
Now, if I want to update a student object which is taken from BLL.FindStudent(), the context.SaveChanges() will return 0, because the context is already disposed in the BLL.FindStudent(), and nothing will be updated to database.
var optStudent = new StudentBO();
var student = optStudent.FindStudent(103);
student.Name = "NewValue";
optStudent.Update(student);
Does anyone have idea on how to use EntityFramework in 3 tire application? or how can I manage the context correctly. I will use navigation propertites very often in the web layer, but I can't always remain connection open to consume the server memory.
There are multiple ways to handle EF context's lifetime. In web apps, usually context is unique for an HttpRequest. For example, if you want to handle this manually in a web application and have a per Thread/HttpRequest EF context, you can do so with the following (Code copied from http://www.west-wind.com/weblog/posts/2008/Feb/05/Linq-to-SQL-DataContext-Lifetime-Management):
internal static class DbContextManager
{
public static DbContext Current
{
get
{
var key = "MyDb_" + HttpContext.Current.GetHashCode().ToString("x")
+ Thread.CurrentContext.ContextID.ToString();
var context = HttpContext.Current.Items[key] as MyDbContext;
if (context == null)
{
context = new MyDbContext();
HttpContext.Current.Items[key] = context;
}
return context;
}
}
}
And then you can easily use:
var ctx = DbContextManager.Current
But I suggest you leave the lifetime management to an IoC framework like Autofac, Castle Windsor, or Ninject which automatically handle the creation/disposal of your registered obejcts along with many other features.
Thanks for your answer Kamyar. I came across this whilst looking for a simple strategy to manage the ObjectContext lifetime without having to use an IoC framework, which seems a bit overkill for my needs.
I also came across your other post here, for disposing of the context at the end of the request.
Thought this might be useful for others coming across this, so just posting my implementation of your code here:
Context manager class -
internal static class MyDBContextManager
{
//Unique context key per request and thread
private static string Key
{
get
{
return string.Format("MyDb_{0}{1}", arg0: HttpContext.Current.GetHashCode().ToString("x"),
arg1: Thread.CurrentContext.ContextID);
}
}
//Get and set request context
private static MyDBContext Context
{
get { return HttpContext.Current.Items[Key] as MyDBContext; }
set { HttpContext.Current.Items[Key] = value; }
}
//Context per request
public static MyDBContext Current
{
get
{
//if null, create new context
if (Context == null)
{
Context = new MyDBContext();
HttpContext.Current.Items[Key] = Context;
}
return Context;
}
}
//Dispose any created context at the end of a request - called from Global.asax
public static void Dispose()
{
if (Context != null)
{
Context.Dispose();
}
}
}
Global.asax (MVC) -
public override void Init()
{
base.Init();
EndRequest +=MvcApplication_EndRequest;
}
private void MvcApplication_EndRequest(object sender, EventArgs e)
{
MyDBContextManager.Dispose();
}