Why is my WCF RIA context throwing FileNotFound exceptions during unit tests? - wcf-ria-services

I'm trying to write unit tests involving my WCF RIA entity proxies and when I try to access an entity's parent or child properties through an association I get a FileNotFoundException when the WebContext class fails to load System.Xml.
For example, I have two entities defined in my web project in Entity Framework - Course and CourseUnit. A Course has many CourseUnit children. I'm not exposing any RIA contexts or anything to my ViewModels, they are all hidden behind interfaces. I'm using Moq to mock these interfaces and return the standard RIA entity proxies to my unit tests.
This works fine when I'm testing things like
Assert.AreEqual("title", course.Title)
where course is an instance of the RIA proxy. However, if I do something like
Assert.AreEqual(0, course.CourseUnits.Count)
I get the following exception
FileNotFoundException was unhandled by
user code Could not load file or
assembly 'System.Xml, Version=2.0.5.0,
Culture=neutral,
PublicKeyToken=7cec85d7bea7798e' or
one of its dependencies. The system
cannot find the file specified.
And similarly if I execute any code in a unit test that involved one of these relationships then the code throws the same exception. Basically if I ever try to access these properties with association relationships from my tests they break.
The exception actually occurs in generated code. It an be found in the file [webProjectName].g.cs in the partial class Course : Entity and happens in the CourseUnits getter.
Any ideas?
Edit - I added a reference to the EntityFramework assembly and the exception has changed to the same thing but System.ComponentModel.DataAnnotations instead of System.Xml. Needless to say I have tried referencing both assemblies in the unit test project, and it didn't work.

Related

Should we add Entity Framework dll to all layers

I am writing a test app using EF code first. I have distributed code among different layers. I thought I would have to install the entity framework package to the data access layer only but what I ended up with is installing the package (adding dlls) to all the layers namely UI, BLL, Models, DAL. Is this okay or I am doing something wrong. Below is sample code to give you an idea of what I am trying to do
Model Layer
This layer is reference in all other layers/projects
namespace Model
{
Public class Sample
{
[ForeignKey("Sample2Id")]
...
}
}
In this layer I had to use Entity Framework dlls because of Data Annotation like [ForeignKey..
DAL
namespace DAL
{
public class SampleContext:DbContext
{
...
}
}
In DAL I only have the context class and migrations
BLL
namespace BLL
{
public class SampleBLL
{
public List<Sample> GetAll()
{
retrn new SampleContext().Samples().ToList()
}
}
}
If I uninstall EF for BLL I get the following error
The type System.Data.Entity.DbContext is defined in an assembly that is not referenced.
UI
namespace UI
{
public class UIHelper
{
public List<Sample> GetSamples()
{
return new SampleBLL().GetAll();
}
}
}
If I uninstall the EF package from UI I get the following error
The Entity Framework provider type
'System.Data.Entity.SqlServer.SqlProviderServices,
EntityFramework.SqlServer' registered in the application config file
for the ADO.NET provider with invariant name 'System.Data.SqlClient'
could not be loaded. Make sure that the assembly-qualified name is
used and that the assembly is available to the running application
I created a sample project which is quite similar to your current setup minus the Model Layer/DAL separation.
I have three projects, DAL (which contains references to the EntityFramework.dll and the EntityFramework.SqlServer.dll), BLL which just calls a method in the DAL, and the UI which just calls the BLL methods.
I had to add the <configSections>, the <entityFramework>, and the <connectionStrings> portions of the app.config of the DAL into the UI's app.config.
When I ran the code the first time, I ran into the same error you ran into. So I looked into the debug folder of my UI Project and noticed that the EntityFramework.dll was copied into the folder due to the DAL's dependency on it. I also noticed that the EntityFramework.SqlServer.dll was NOT copied into the debug folder despite the DAL also having a dependency on it.
I copied the EntityFramework.SqlServer.dll into the debug folder of the UI Project then re-ran the project then, Viola! My code ran as expected.
It looks like the problem here is that one dll is not being copied into the UI Project debug folder as it is expected to.

Oracle with Entity Frameworks throws "did not return an object that inherits from DbProviderServices"

I'm working on a solution that uses Entity Framework and Oracle all of which are new territory for me. I'm trying to run some integration tests (these were in place when I got here) and I'm getting the following error:
The 'Instance' member of the Entity Framework provider type 'Devart.Data.Oracle.Entity.OracleEntityProviderServices,
Devart.Data.Oracle.Entity, Version=8.4.407.0, Culture=neutral, PublicKeyToken=09af7300eec23701' did not return an object
that inherits from 'System.Data.Entity.Core.Common.DbProviderServices'. Entity Framework providers must inherit from this
class and the 'Instance' member must return the singleton instance of the provider. This may be because the provider
does not support Entity Framework 6 or later
So I've checked the web.config and it's pointing to a completely different version of that DLL:
<provider invariantName="Devart.Data.Oracle"
type="Devart.Data.Oracle.Entity.OracleEntityProviderServices,
Devart.Data.Oracle.Entity,
Version=8.3.146.6,
Culture=neutral, PublicKeyToken=09af7300eec23701" />
In fact, I can't find a reference to 8.4.407.0 (which I know is installed) anywhere in the solution, but it is in the GAC. Can anyone help me with some pointers on this, banging my head against the wall all morning.
Thanks

Nested Transactions In EF6

I have a method where the DBContext is pass in (this is only POC code).
I then try to open another nested transaction, With this code
using (var cxt = new TestEntities(context.Database.Connection, false))
{
using (DbContextTransaction dbContextTransaction = cxt.Database.BeginTransaction())
{
The call to "BeginTransaction" gives this error:
An exception of type 'System.Data.Entity.Infrastructure.UnintentionalCodeFirstException' occurred in TestEF6.exe but was not handled in user code
Additional information: The context is being used in Code First mode with code that was generated from an EDMX file for either Database First or Model First development. This will not work correctly. To fix this problem do not remove the line of code that throws this exception. If you wish to use Database First or Model First, then make sure that the Entity Framework connection string is included in the app.config or web.config of the start-up project. If you are creating your own DbConnection, then make sure that it is an EntityConnection and not some other type of DbConnection, and that you pass it to one of the base DbContext constructors that take a DbConnection. To learn more about Code First, Database First, and Model First see the Entity Framework documentation here: http://go.microsoft.com/fwlink/?LinkId=394715
I have a Database First Model
Any clues?
Regards
GregJF

Entity Framework inheritance over different assemblies

I'm quite new to Entity Framework, but the more I worked with it, the more I actually liked it. But now my passion is at risk, as I'm struggeling with an issue that already made me crush my head against the wall.
The problem is the following:
I'm using Entity Framework 5.0 with code-first approach plus inheritance for my business models represented by Table Per Hierarchy. At first I had all of my entity types, that were supposed to be mapped, in the same assembly as my DbContext (which worked fine for both TPH and TPT). But as they also contain logic that is dependent on other assemblies, this turned out as no good approach since it caused circular dependencies because those assemblies also need to have knowledge of the Data Access Layer, which in turn has to have knowledge of the entity types that it is supposed to map).
I solved this issue by introducing a CommonObjects project, where I now keep all of my abstract classes and stripped out the concrete descendents (containing the logic, etc.) of those base classes into the specific projects, which are responsible for them.
(see: Circular Dependency Solution)
It compiled and everything seemed to fit the way I imagined it.
But now it turned out that Entity Framework seems to struggle with the derivates being in a different assembly than the base classes.
During runtime, when trying to access the DbContext the first time, the compiler threw an InvalidOperationException saying:
The abstract type 'Foo.Bar.AbstractClass' has no mapped descendents
and so cannot be mapped. Either remove 'Foo.Bar.AbstractClass' from
the model or add one or more types deriving from
'Foo.Bar.AbstractClass' to the model.
So EF is obviously not able to find the descendents, as it only knows the base classes (which are in the CommonObjects project), but the descendents are in a different assembly.
DbSet<AbstractClass> AbstractClasses { get; set; }
According to this question:
Entity Framework Code First and Multiple Assemblies
I tried to add the following code to the constructor of my derived DbContext:
((IObjectContextAdapter)this).ObjectContext.MetadataWorkspace.LoadFromAssembly(
Assembly.Load("Foo1"));
But that did not work for me. While debugging and watching the MetadataWorkspace the method "LoadFromAssembly" did obviously not have any effect on the MetadataWorkspace and its items (no types were loaded from assembly Foo1).
What am I missing here?
Thanks for your answers in advance.
Ben
EDIT: This only barely works and isn't worth it, and doesn't work at all if you're using CodeFirst.
I have encountered the same issue with code first. I tried your method of reflection. This seems a bit wonky, but you can trick EF into being okay with your set up with an internal class.
internal class ClassToMakeEFHappy : AbstractClass {}
I just created that in the same file as my AbstractClass definition and it did the trick.

How do I pass a connection string to the constructor of a database-first DBContext with Entity Framework 4.1?

For various reasons I would like to not store the connection string for my Entity Framework DB model in one of the various .config files. (I am using the latest and greatest DBContext API with the new Entity Framework version 4.1, .NET 4 and Visual Studio 2010 C#.) However, the code generation template for DBContext only creates a single parameterless constructor. (If I don't use the DBContext API, then my entity framework model has 7 different constructors to chose from, including the one I want.)
The only way I could figure out how to do this was to directly modify the code-generation template (context.tt file) to give me the constructor I want (example code below). This works, but it feels like I'm doing it "the hard way". What is the correct way to get a DBContext constructor that accepts a connection string?
public <#=Code.Escape(container)#>(string connectionString)
: base(connectionString)
{
<#
WriteLazyLoadingEnabled(container);
#>
}
One final note in case it might help somebody else. Although this method works, it took me a while to realize that the "connection string" is not strictly the DB connection string, but rather the special entity framework connection string which contains the DB connection string (just like what would be stored in the app.config file).
Your approach looks like the most correct way to do this. It's what the t4 templates were created for, and you're basically doing the same thing that the model-first templates do by default.
Another possibility would be to make the db context class be partial (if it isn't by default) and create another partial class file alongside it to add the constructor you want. But it seems likely that you'll want all of your t4-generated contexts to follow this pattern, so I think it's best to leverage the code generation to do this automatically the way you do in the question.