Setting ConnectionTimeout when using EntityFramework - entity-framework

I would like to set the ConnectionTimeout to something other than the default, which is 15 seconds. I have inherited some code that uses EntityFramework and the app.config looks like this:
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxxxx" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=.\SQLEXPRESS; Integrated Security=True; ConnectionTimeout=30; MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
<parameters>
<parameter value="Data Source=.\SQLEXPRESS; Integrated Security=True; ConnectionTimeout=30; MultipleActiveResultSets=True" />
</parameters>
</defaultConnectionFactory>
</entityFramework>
I'm the one who added the sectino in an attempt to get things working. I can tell it's not working be setting a breakpoint at:
var adapter = (IObjectContextAdapter) this;
var objectContext = adapter.ObjectContext;
objectContext.CommandTimeout = CommandTimeoutSeconds;
int test = objectContext.Connection.ConnectionTimeout;
test is always 15. What is going on? Can someone tell me how to set ConnectionTimeout? I have tried both "ConnectionTimeout" and "Connection Timeout" I.e. no space vs. space.
Can someone help me? I'm pulling my hair out. I'm sure it's a simple fix!
Dave
Additional info. In response to comment, here is my DbContext derived class...
public class SessionDataContext : DbContext
{
// Command timeout (seconds)
private const int CommandTimeoutSeconds = 30;
/// <summary>
/// Constructor that takes db name.
/// The connection string and db itself is configured in the this project's app.config file
/// </summary>
/// <param name="dbName"></param>
public SessionDataContext(string dbName) : base(dbName)
{
Database.SetInitializer(new SessionDataContextInitializer());
// Set timeout (based on code from http://stackoverflow.com/questions/6232633/entity-framework-timeouts)
var adapter = (IObjectContextAdapter) this;
var objectContext = adapter.ObjectContext;
objectContext.CommandTimeout = CommandTimeoutSeconds;
int test = objectContext.Connection.ConnectionTimeout;
}
/// <summary>
/// Session table's records
/// </summary>
public DbSet<Session> Sessions { get; set; }
/// <summary>
/// SessionType table's records
/// </summary>
public DbSet<SessionType> SessionTypes { get; set; }
}

It was stupidity on my part that was causing the problem! I put my answer here in case anyone in the future has this problem. Everything I typed above is correct and will work fine. However, the app.config file I was looking at was in a class library (our DataAccess layer). In fact, it was not being used at all and default EntityFramework settings were being used. I'm mot sure what led me to try it, but I moved the app.config settings from the DataAccess layer app.config to the main app.config and all worked beautifully. About all I can say in my defense other than I inherited the code is that it's not clear to me to see that the values in the app.config are not being used and one does not call them or use them in one's own code. Rather, MultipleActiveResultSets and ConnectionTimeout are used by the underlying Entity Framework.

Related

Hardcoded EF6 Connectionstring names used from dotnet core

We have an existing .NET Framework library with Entity Framework 6 and static methods like this:
public class OrderManager
{
public static OrderDTO GetOrderByOrderId(int oid)
{
var entities = new MyEntities();
....
}
}
where MyEntities have a hardcoded connectionstring name
internal partial class MyEntities : DbContext
{
public SSE3Entities() : base("name=MyEntities") {}
}
When used in a ASP.NET application, the web.config have a connectionstrings defined like this:
<connectionStrings>
<add name="MyEntities" connectionString="metadata=res://*/M..." providerName="System.Data.EntityClient" />
</connectionStrings>
But how can I reuse this library in a aspnet core application. Tried:
{
"ConnectionStrings": {
"MyEnties": "metadata=res://*/M...",
},
"Logging": {
...
}
}
I know passing the connectionstring into the OrderManager constructor is what we should have done years ago, but changing it now requiers a lot of work.
Are there any ways we can make EF read the new configurations system?
Or could we maybe write some settings to the old ConfigurationManager?
I tried dropping in a web.config without any luck
add System.Configuration.ConfigurationManager from nuget
add a file app.config
.net core applictaion is a consle app, so it find app.config first
app.config:
<appSettings>
<add key="webpages:Version" value="2.0.0.0"/>
</appSettings>
This solution will work for ASPNET Core MVC 2.0, 2.2 and 3.0 In your app root go find the appsetting.json file and modify the connection string.
{
"ConnectionStrings": {
"DefaultConnection": "Data Source=DESKTOP-3R4MR9H\\SQLSERVER3R4MR9;Initial
Catalog=ASPNetCoreMVC;Persist Security Info=True;User
ID=sa;Password=********;"
},
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}

Can't see EF database in SQL Server Management Studio

I have created a database using EF code-first like there http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4-1-code-first-walkthrough.aspx. But when I input data to db by add() and then call savechanges() I don't see new database in SQL Server databases folder and there no exceptions. Is it right? Where can I find my database and how to put it in databases folder?
I work with this code:
public class Name
{
public long NameId { get; set; }
public string FullName { get; set; }
}
public class InfoContext : DbContext
{
public DbSet<Name> Names { get; set; }
}
Then I call it:
var db = new InfoContext();
var Names = new Name
{
NameId = 1,
FullName = "test"
};
db.Names.Add(Name);
db.SaveChanges();
var test = db.Names.Find(1);//there I get correct value
I have connectionString in web.config like this:
<connectionStrings>
<add name="InfoName" providerName="System.Data.SqlClient"
connectionString="Server = .\MYINSTANCE; Initial Catalog=mydbname;" />
</connectionStrings>
Based on your comments you need to modify the web.config file in your project root (not the one in your Views folder. In there you can add a section as follows:
<connectionStrings>
<add name="EFDbContext" connectionString="Data Source = .; Initial Catalog = ITSDB; Integrated Security = true" providerName="System.Data.SqlClient"/>
</connectionStrings>
The name property of the element is the DbContext name of your Data model, so if your class is defined as:
public class SomeContext : DbContext
{
...
}
Then your config should be:
<connectionStrings>
<add name="SomeContext" connectionString="Data Source = .; Initial Catalog = ITSDB; Integrated Security = true" providerName="System.Data.SqlClient"/>
</connectionStrings>
As for the connection string, its dependent on your database.
Check the defaultConnectionFactory type in your config. I expect it is set to LocalConnectionFactory, as this seems to be default.
Change it to the following and your SQL instance will be used.
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
<parameters>
<parameter value="Data Source=.; Integrated Security=True; MultipleActiveResultSets=True;" />
</parameters>
</defaultConnectionFactory>
Your DB should appear in SQL Management Studio (SQLMS) with a name that matches the namespace and DbContext.
Or you can just put in "Data Source = " value your server's name which selected in you SQL Management Studio.
<connectionStrings>
<add name="SomeContext" connectionString="Data Source = **Server'sName**; Initial Catalog = ITSDB; Integrated Security = true" providerName="System.Data.SqlClient"/>

how to prevent Entity-Framework to generate N'..' prefixed unicode strings?

I use EF 4.1 Code-First ,
the problem is: EF generates all the unicode fields with N'..' prefix by default. like this :
exec sp_executesql
N'SELECT ...
FROM ...
WHERE [Title] LIKE #p__linq__0 ESCAPE N''~''',
N'#p__linq__0 nvarchar(4000)',
#p__linq__0=N'%...%'
but it cause me some problems in some characters. I want to know if there is a way to prevent EF of adding N prefix or not?
You can wrap your strings in AsNonUnicode method as mentioned at http://msdn.microsoft.com/en-us/library/system.data.objects.entityfunctions.asnonunicode.aspx this will generate normal strings.
Another solution would be to use CommandInterceptors and modify the resulting sql query before it gets executed.
I had similar problems with an oracle database and ODP.net provider.
AsNonUnicode didn't solved my problem.
EF 6 provides the ability to intercept the context using IDbCommandInterceptor before and after it performs the ExecuteNonQuery, ExecuteScalar, ExecuteReader operations to the database. You will need to configure the interceptor either by using config file or code-based configuration.
Config file:
<entityFramework>
<interceptors>
<interceptor type="EfSample.EfCommandInterceptor, EfSample">
</interceptor>
</interceptors>
</entityFramework>
Code-based config:
public sealed class EntityFrameworkConfiguration : DbConfiguration
{
public EntityFrameworkConfiguration ()
{
this.AddInterceptor(new EfCommandInterceptor());
}
}
Create the CommandInterceptor as shown below:
public sealed class EfCommandInterceptor
: DbCommandInterceptor
{
/// <summary>
/// Called when Reader is executing.
/// </summary>
/// <param name="command"></param>
/// <param name="interceptionContext"></param>
/// <inheritdoc />
public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
if(command.CommandText.Contains("N''"))
{
command.CommandText = command.CommandText.Replace("N''", "''");
}
base.ReaderExecuting(command, interceptionContext);
}
}

'String cannot have zero length' error when using EF Tracing Data Provider

I am trying to incorporate 'EF Tracing Data Provider' into an existing MVC2 app using VS2010, .NET 4.0 in order to log all SQL commands. I have no interest at this time in the caching provider. I beleive I have followed all the steps listed in the blog posting. BLOG POST My project does compile without error, however when I attempt to run the project I get the following error:
'String cannot have zero length.' The error points to Extended_JCIMS_MVC2_EF_Entities.cs Line: 25
Line 25: public ExtendedJCIMS_DevEntities(string connectionString)
Line 26: :base(EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers(
I am unable to determine what is causing this error. I assume the error is referring to the connection string from the Web.Config file. It does not like the 'connectionString' variable. I'm obviously doing something worng. I would appreciate a push in the right direction.
The relevant bits are as follows:
Web.config
--------------------------------------------------------------------------
<add name="JCIMS_DevEntities"
connectionString="metadata=res://*/;provider=System.Data.SqlClient;provider connection string="Data Source=MyServer;Initial Catalog=MyDatabase;User ID=MyUser;Password=myPassWord;MultipleActiveResultSets=True""
providerName="System.Data.EntityClient"/>
<system.data>
<DbProviderFactories>
<add name="EF Tracing Data Provider" invariant="EFTracingProvider" description="Tracing Provider Wrapper"
type="EFTracingProvider.EFTracingProviderFactory, EFTracingProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />
<add name="EF Generic Provider Wrapper" invariant="EFProviderWrapper" description="Generic Provider Wrapper"
type="EFProviderWrapperToolkit.EFProviderWrapperFactory, EFProviderWrapperToolkit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />
</DbProviderFactories>
</system.data>
Global.ascx
-----------------------------------------------------------------------
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
//EFTracingProviderConfiguration - LOG ALL Sql commands
EFTracingProviderConfiguration.LogToFile = Server.MapPath("~/JCIMS_MVC2_EF_SQL_Logfie.txt");
}
Extended_JCIMS_MVC2_EF_Entities.cs
--------------------------------------------------------------------------
namespace JCIMS_MVC2_EF.DomainModel
{
/// <summary>
/// Partial calss that Extends the EF Datacontext Class
/// </summary>
public partial class ExtendedJCIMS_DevEntities : JCIMS_DevEntities
{
private TextWriter logOutput;
public ExtendedJCIMS_DevEntities()
: this("name=JCIMS_DevEntities")
{
}
public ExtendedJCIMS_DevEntities(string connectionString)
: base(EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers(
connectionString,
"EFTracingProvider"
))
{
}
//... and more
}
}
SearchRepository.cs
------------------------------------------------------------------
public class SQLSearchRepository : ISearchRepository
{
//Database connection
private ExtendedJCIMS_DevEntities db = new ExtendedJCIMS_DevEntities(); // tracing version
public IEnumerable<SearchResults> ListAll(string strSearch, string chkSearch)
{
return (from s in db.Schools....
// and more...
}
Appreciate any assistance anyone can give me...
Have you debugged and confirmed that the connectionString passed into the ExtendedJCIMS_DevEntities method is not null or empty? That's what the error seems to indicate.

Registering custom tracking participants through code in workflow foundation 4.0

I'm having trouble trying to attach a custom tracking participant in workflow foundation 4.0. I have a class that inherits from TrackingParticipant but I cannot see any other way of attaching it to my WorkflowServiceHost other than through lots of messy app.config entries like the SDK example demonstrates below (in the system.servicemodel element). This option seems to require a lot of extra overhead and classes to be created, when I just want a simple custom tracking participant to listen to my CustomTrackingRecord.Data.Add(key, value) calls.
public class CustomTracking : TrackingParticipant
{
protected override void Track(TrackingRecord record, TimeSpan timeout)
{
CustomTrackingRecord innerRecord = (CustomTrackingRecord)record;
var workflowInstanceId = innerRecord.InstanceId;
Console.WriteLine("Track called for workflow '{0}'", workflowInstanceId);
}
}
How can I register my above custom tracking participant through code (and not config like below) to a workflowServiceHost instance?
<extensions>
<behaviorExtensions>
<add name="historyFileTracking" type="Microsoft.Samples.HistoryFileTrackingExtensionElement, HiringRequestProcessDefinition, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
<behaviors>
<serviceBehaviors>
<behavior>
<historyFileTracking profileName="RequestStoryTracking" path="..\..\..\Data\RequestHistory\"/>
</behavior>
</serviceBehaviors>
</behaviors>
<tracking>
<profiles>
<trackingProfile name="RequestStoryTracking">
<workflow activityDefinitionId="*">
<customTrackingQueries>
<customTrackingQuery name="*" activityName="*" />
</customTrackingQueries>
</workflow>
</trackingProfile>
</profiles>
</tracking>
Just add it as a workflow extension to the WorkflowServiceHost.
var host = new WorkflowServiceHost(....);
var tracker = new CustomTracking();
host.WorkflowExtensions.Add(tracker);
host.Open();