A default DbContext context must exist, or a context factory must be provided - entity-framework

I'm getting the following error while performing "Bulk Insert" using EntityFramework extensions.
_indnCon.BulkInsert(_DataToTrans, operation => operation.IncludeGraph = true);
Exception occurs in the above line and here is the exception.
A default DbContext context must exist,
or a context factory must be provided (EntityFrameworkManager.ContextFactory).
This setting is required for some features like IncludeGraph.
Here I'm passing the Connection String to the DBContext manually.
using (InsightDataContext _indnCon = new InsightDataContext(_connectionString))
Can anyone help?

It seems that IncludeGraph feature needs to be able to create a new instance of your context, even if you already instantiated the context yourself in this scope. So, as the message says, you can try setting a default constructor for your context:
EntityFrameworkManager.ContextFactory = context => new CurrentContext(yourConnectionString);
The info comes from this post.

Related

How to mock DbUpdateConcurrencyException

I'm trying to mock function in my service to throw a DbUpdateConcurrencyException. My code only needs to check for an exception of type DbUpdateConcurrencyException and doesn't need to read the exception message or list of entries that the constructor asks for.
I want to set up the Mock by calling a parameter-less constructor for DbUpdateConcurrencyException, but that doesn't exist in EFCore.
var mockService = new Mock<IMyService>();
mockService.Setup(service => service.UpdateFooAsync(It.IsNotNull<Data.Foo>())).Throws(new DbUpdateConcurrencyException());
I've tried calling new DbUpdateConcurrencyException() with some parameters, but there's some checks that happen on the parameters that prevents me from doing this with null/empty data.
new DbUpdateConcurrencyException(null, null) gives:
Message: System.ArgumentNullException : Value cannot be null.
Parameter name: entries
new DbUpdateConcurrencyException("", new List<IUpdateEntry>()) gives:
Message: System.ArgumentException : The collection argument 'entries' must contain at least one element.
Is there a way in Moq that I can mock the DbUpdateConcurrencyException without having to go through the checks that the constructor has?
Based on docs you have shared in comments you should use ctor with two parameters. The trick is to provide not null string and not empty List<IUpdateEntry>, moq could help you with that, e.g.
new DbUpdateConcurrencyException(string.Empty, new List<IUpdateEntry>{Mock.Of<IUpdateEntry>()});

Calling SaveChanges after SaveChanges fails

I have the following test code:
try
{
Product product = productService.GetProductById(1502);
product.ProductName = "TEST PRODUCT NAME";
throw new ArgumentException("");
//Do some other DB updates
//Call SaveChanges
productService.SaveChanges();
}
catch(Exception ex)
{
logService.InsertLog(LogTypeEnum.Error, "test", ex);
logService.SaveChanges();
}
The problem is that my services share a context per request (using StructureMaps HttpContextScoped). So when the failure occurs and I call logService.SaveChanges it saves the products new name. However I lose atomicity because the "other DB updates" will not be saved to the DB. What would be the correct way to implement this?
This is always going to be a problem with context per-request. In a large project I started out with context per-request too, but have gradually removed it due to problems like this.
I would suggest identifying the scenarios like this where you are likely to need to write to your DB without calling SaveChanges - if it's all limited to this log service then perhaps you should re-implement this without the dependence on the context? Alternatively you should be able to specify a custom way of creating the log service with its own context (i.e. not just having one injected by the constructor).
I'm not familiar with the Structuremap syntax so here's something from Autofac which would do the same...
builder.RegisterType<MyContext>().InstancePerRequest(); // As you have already
builder
.Register(c => new LogService(new MyContext())
.As<ILogService>().InstancePerRequest();
This would construct LogService using an explicitly created context rather than the per-request instance which would've been injected had I registered it normally.

WebAPI/Unity Intercept Request and Change ConectionString Unity Container for EF Context

I'm building an API that needs to connect to a different database per request. Currently I'm using EF. These databases all have the same schema, therefore I can share a DbContext class. I have repositories to abstract persistence, and these are the ones using the DbContext objects.
Unity is handling dependency resolution, it is injecting my repositories with DbContext objects, and the repos on the controllers. Basically with zero configuration. I understand that probably I may need to create my own HttpRequestLifeCycle thing as suggested in this answer to make sure I have the same DbContext object through out the request.
Now, I would like to configure a ConnectionString to be used by Unity when creating DbContext objects to pass along to the repositories.
These ConnectionString will come from a repository (most likely a different fixed database), based on a parameter on my route. So, my intention is to have a delegating handler inspect the route, get the parameter, get the ConnectionString and tell Unity: "here, use this particular connection string when creating DbContext objects for my repositories during this request."
First, is my approach reasonable? Is this achievable?
How would this dynamic parameter configuration done?
Thanks in advance,
Yes, this is reasonable and achievable and frankly, easy.
Just approach this differently, instead of thinking how to inject connection strings, just register a factory for your db contexts. In the factory method, use the route information to read the connection string and return the context.
containe.Register<MyDbContext>( new InjectionFactory(
c => {
// this is the factory method
// the code will be executed upon each resolution
String routeInfo = GetTenantFromCurrentRoute();
String cs = GetCsFor( routeInfo );
return new MyDbContext( cs );
}, new PerHttpRequestLifetimeManager() )

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

In ADO.Net Data Services how do I check if an entity is already in the context?

I have an ADO.Net Data Service that I am using to do a data import. There are a number of entities that are linked to by most entities. To do that during import I create those entities first, save them and then use .SetLink(EntityImport, "NavigationProperty", CreatedEntity). Now the first issue that I ran into was that the context did not always know about CreatedEntity (this is due to each of the entities being imported independently and a creation of a context as each item is created - I'd like to retain this functionality - i.e. I'm trying to avoid "just use one context" as the answer).
So I have a .AddToCreatedEntityType(CreatedEntity) before attempting to call SetLink. This of course works for the first time, but on the second pass I get the error message "the context is already tracking the entity".
Is there a way to check if the context is already tracking the entity (context.Contains(CreatedEntity) isn't yet implemented)? I was thinking about attempting a try catch and just avoiding the error, but that seems to create a new CreatedEntity each pass. It is looking like I need to use a LINQ to Data Services to get that CreatedEntity each time, but that seems innefficient - any suggestions?
I think you should look at the EntityState property of your entity.
Only if it is of the value EntityState.Detached than you have to add it to your context.
Do not forget the following remark:
This enumeration has a FlagsAttribute
attribute that allows a bitwise
combination of its member values.
I would create a extension method:
public static class EntityObjectExtensions
{
public static Boolean IsTracked(this EntityObject self)
{
return (self.EntityState & EntityState.Detached) != EntityState.Detached;
}
}
When trying to check whether the context was tracking the entity that I wanted to update (or add) I was pretty disapointed when I found that the context.Entites.Contains(currentItem) didn't work.
I got around it using:
if (context.Entities.Where(entities => entities.Entity == currentItem).Any())
{
this.service.UpdateObject(currentItem);
}