Why is my Entity Framework connection string not working - c#

I am trying to connect to a database without using App.Config but i keep getting the following error:
An unhandled exception of type 'System.Data.Entity.Core.EntityException' occurred in EntityFramework.dll
Additional information: The underlying provider failed on ConnectionString.
I can't see where I've gone wrong so i thought i'd ask here.
namespace MyNameSpace
{
using System;
using System.Data.Entity;
using System.Data.Entity.Core.EntityClient;
using System.Data.Entity.Infrastructure;
public partial class Entities : DbContext
{
public Entities()
: base(entityString.ToString())
{
}
public static EntityConnectionStringBuilder entityString = new EntityConnectionStringBuilder()
{
Provider = "System.Data.SqlServerCe.4.0",
Metadata = "res://*/RS.csdl|res://*/RS.ssdl|res://*/RS.msl",
ProviderConnectionString = #"C:\RestOfPath\database.sdf;Password=3476dfg423434563466e85rcsd"
};
}
}
Thank you in advance for your help.

The problem is that you are passing your sdf file directly on your connection string. Try changing:
ProviderConnectionString = #"C:\RestOfPath\database.sdf;Password=3476dfg423434563466e85rcsd"
To:
ProviderConnectionString = #"Data Source=C:\RestOfPath\database.sdf;Password=3476dfg423434563466e85rcsd"
Or better yet, use a SqlCeConnectionStringBuilder to construct this property:
var connectionStringBuilder = new SqlCeConnectionStringBuilder();
connectionStringBuilder.DataSource = #"C:\RestOfPath\database.sdf";
connectionStringBuilder.Password = "3476dfg423434563466e85rcsd";
EFConnectionBuilder.ProviderConnectionString = connectionStringBuilder.ToString(),

Try this : make this parameterise
public Entities(string connString)
: base(connString)
{
}
and pass string connection string when creating object of Context class.
public class TestController : Controller
{
Entity _context = new Entity("data source=Dev-4;initial catalog=test1;
integrated security=True;MultipleActiveResultSets=True;
App=EntityFramework");
}

Try this : here you din't need to pass connection string again and again -->
public Model1()
: base(connString)
{
}
public static string connString = "data source=tesst;initial catalog=test1;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework";
Use This method when using Database First Model of Entity Framework :
public test1Entities()
: base(nameOrConnectionString: ConnectionString())
{
}
private static string ConnectionString()
{
SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder();
sqlBuilder.DataSource = "DEV-4";
sqlBuilder.InitialCatalog = "test1";
sqlBuilder.PersistSecurityInfo = true;
sqlBuilder.IntegratedSecurity = true;
sqlBuilder.MultipleActiveResultSets = true;
EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
entityBuilder.ProviderConnectionString = sqlBuilder.ToString();
entityBuilder.Metadata = "res://*/";
entityBuilder.Provider = "System.Data.SqlClient";
return entityBuilder.ToString();
}

Related

Migrating from StackExchangeRedisCacheClient to RedisCacheClient

I am building a project based on StackExchangeRedisCacheClient and obsolete has popped out:
'StackExchangeRedisCacheClient' is obsolete: 'This interface will be removed with the next major. Please use RedisCacheClient instead.'
so i'm trying to move from StackExchangeRedisCacheClient to RedisCacheClient
unfortunately there is no documentation or some helpful info for doing that.
how do i create a cache client? with RedisCacheClient ? the require args are 'RedisCacheClient(IRedisCacheConnectionPoolManager, ISerializer, RedisConfiguration)'
i have looked at the following link and tried to implement a Single pool with no success https://github.com/imperugo/StackExchange.Redis.Extensions/issues/176#
couldn't create a cacheClient after providing the connection string.
StackExchangeRedisCacheClient:(works fine)
public CacheManager()
{
string connectionString = "localhost:300....."
var serializer = new NewtonsoftSerializer();
cacheClient = new StackExchangeRedisCacheClient(serializer, connectionString);
clientName = cacheClient.Database.Multiplexer.ClientName;
}
RedisCacheClient:
public CacheManager()
{
string connectionString = "localhost:300....."
var serializer = new NewtonsoftSerializer();
cacheClient = new RedisCacheClient( *** ??? *** );
clientName = cacheClient.Database.Multiplexer.ClientName;
}
As per https://github.com/imperugo/StackExchange.Redis.Extensions/issues/176 if you don't care about having multiple connections you can use the following class:
internal class SinglePool : IRedisCacheConnectionPoolManager
{
private readonly IConnectionMultiplexer connection;
public SinglePool(string connectionString)
{
this.connection = ConnectionMultiplexer.Connect(connectionString);
}
public IConnectionMultiplexer GetConnection()
{
return connection;
}
}

Override DbContext EF6

I'm trying to understand how to dynamically create the connection string for my DbContext, but my application says it has no connection string in the app.config (and that's correct because I don't want to use it in the app.config or web.config). This is what I have:
In my solution I have a project called InterfaceApp. It is a ASP.NET MVC 5 application. When I put my connection string in the web.config all seems to be working fine.
In my solution I have an other project called InterfaceApp.Connector.Erp1. Here I want to connect to an ERP application and fetch some items. So in my repository I have:
namespace InterfaceApp.Connector.Erp1.Repository
{
internal class ItemRepository : IItemRepository
{
public IEnumerable<Item> Items
{
get
{
List<Item> items = new List<Item>();
using (Models.Entities context = new Models.Entities())
{
var itemList = context.Items.ToList();
foreach(var item in itemList)
{
items.Add(new Item() { Id = item.ID, Description = item.Description, ItemCode = item.ItemCode });
}
}
return items.ToList();
}
}
}
}
I've created a partial class to connect to the database:
namespace InterfaceApp.Connector.Erp1.Models
{
public partial class Entities
{
public Entities(string connectionString)
: base(ConnectionString())
{
}
private static string ConnectionString()
{
SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder
{
DataSource = "MyServer", //When this works it will be dynamic
InitialCatalog = "XXX", //When this works it will be dynamic
PersistSecurityInfo = true,
IntegratedSecurity = true,
MultipleActiveResultSets = true,
};
var entityConnectionStringBuilder = new EntityConnectionStringBuilder
{
Provider = "System.Data.SqlClient",
Metadata = "res://*/Models.Erp1Model.csdl|res://*/Models.Erp1Model.ssdl|res://*/Erp1Model.msl",
ProviderConnectionString = sqlBuilder.ConnectionString
};
return entityConnectionStringBuilder.ConnectionString;
}
}
}
The Context class that is auto-generated by EF6 (Db First) looks like this:
namespace InterfaceApp.Connector.Erp1.Models
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class Entities : DbContext
{
public Entities()
: base("name=Entities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Items> Items { get; set; }
}
}
When I run my application, the debugger stops at the auto-generated class, but not at my partial class. Because it cannot find the connection string Entities in my app.config and web.config it generates an error saying that the connection string is not found in the application config file. What am I doing wrong?
When you are calling the DbContext, you're calling the empty constructor (new Models.Entities()). Thus, it will call the auto-generated DbContext. If you want to call your partial class, you need to call it explicitly with the parameter.
Remember when you create a partial class, the compiler merges them, so you have this when compiled :
public partial class Entities : DbContext
{
public Entities()
: base("name=Entities")
{
}
public Entities(string connectionString)
: base(ConnectionString())
{
}
private static string ConnectionString()
{
SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder
{
DataSource = "MyServer", //When this works it will be dynamic
InitialCatalog = "XXX", //When this works it will be dynamic
PersistSecurityInfo = true,
IntegratedSecurity = true,
MultipleActiveResultSets = true,
};
var entityConnectionStringBuilder = new EntityConnectionStringBuilder
{
Provider = "System.Data.SqlClient",
Metadata = "res://*/Models.Erp1Model.csdl|res://*/Models.Erp1Model.ssdl|res://*/Erp1Model.msl",
ProviderConnectionString = sqlBuilder.ConnectionString
};
return entityConnectionStringBuilder.ConnectionString;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Items> Items { get; set; }
}
What you probably need a a method to create your DbContext and call it instead of calling a new DbContext.
public static Entities Create()
{
return new Entities(ConnectionString());
}
Then you can use it this way :
using (var context = Entities.Create())
{
//...
}

EntityFramework 6 Code-based configuration of connection string for database-first

I'm attempting to make an existing application work without an app.config (it is required due to a very specific environment). Problem is that it's heavily relying on EntityFramework 6 to work with an SQL-Server.
I'm trying to use a code-based configuration, but I can't figure out how to provide a correct connection string through my configuration class.
I made a configuration class:
public class MyConfiguration : DbConfiguration
{
public MyConfiguration()
{
SetDefaultConnectionFactory(new MyConnectionFactory());
SetProviderServices("System.Data.SqlClient", System.Data.Entity.SqlServer.SqlProviderServices.Instance);
}
}
Then provided it to my DbContext (Generated by EF automatically from bd):
[DbConfigurationType(typeof(MyConfiguration))]
public partial class TestModelEntities
{
}
With a custom connection factory:
public class MyConnectionFactory : IDbConnectionFactory
{
public DbConnection CreateConnection(string nameOrConnectionString)
{
var newConnStringBuilder = new SqlConnectionStringBuilder
{
UserID = "user",
Password = "pass",
InitialCatalog = "databaseName",
DataSource = "serverName"
};
var entityConnectionBuilder = new EntityConnectionStringBuilder
{
Provider = "System.Data.SqlClient",
ProviderConnectionString = newConnStringBuilder.ToString(),
Metadata = #"res://*/TestModel.csdl|
res://*/TestModel.ssdl|
res://*/TestModel.msl"
};
var newDbConnect = new EntityConnection(entityConnectionBuilder.ToString());
return newDbConnect;
}
}
However. When I test it, I get an UnintentionalCodeFirstException. Why? What am I missing?
You should provide connection string to your context via :base(connectionString). Create a class as below:
public class ConnectionStringBuilder
{
public static string Construct()
{
var newConnStringBuilder = new SqlConnectionStringBuilder
{
UserID = "user",
Password = "pass",
InitialCatalog = "databaseName",
DataSource = "serverName"
};
var entityConnectionBuilder = new EntityConnectionStringBuilder
{
Provider = "System.Data.SqlClient",
ProviderConnectionString = newConnStringBuilder.ToString(),
Metadata = #"res://*/TestModel.csdl|
res://*/TestModel.ssdl|
res://*/TestModel.msl"
};
return entityConnectionBuilder.ToString();
}
}
Then modify your Context constructor to look like this:
public DbContext()
: base(ConnectionStringBuilder.Construct())
{
}
It should work fine now. (source)

Strange behavior creating a new Database with Npgsql and Entity Framework

I'm trying to create a new database with npgsql and EF 6. This is my code:
using System.Data.Common;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Migrations;
using System.Data.Entity;
using System.Data.Entity.Migrations.Sql;
using Npgsql;
using NUnit.Framework;
namespace EntityFramework.PostgreSql.Test.IntegrationTests
{
[TestFixture]
public class PostgreSqlMigrationSqlGeneretorHistoryTest
{
private const string ConnectionString = "Server=127.0.0.1;Port=5432;Database=testEF6;User Id=postgres;Password=p0o9i8u7y6;CommandTimeout=20;Preload Reader = true;";
private const string ProviderName = "Npgsql";
[Test]
public void CreateNewDatabase()
{
const string cs = "Server=127.0.0.1;Port=5432;Database=testEFxx;User Id=postgres;Password=p0o9i8u7y6;CommandTimeout=20;Preload Reader = true;";
var db = new LocalPgContext(cs);
if (!db.Database.Exists())
db.Database.Create();
var exists = db.Database.Exists();
db.Database.Delete();
Assert.IsTrue(exists);
}
public class LocalPgContext : DbContext, IDbProviderFactoryResolver, IDbConnectionFactory
{
public LocalPgContext(string nameOrConnectionString) : base(nameOrConnectionString)
{
Database.SetInitializer(new CreateDatabaseIfNotExists<LocalPgContext>());
}
public DbProviderFactory ResolveProviderFactory(DbConnection connection)
{
return DbProviderFactories.GetFactory("Npgsql");
}
public DbConnection CreateConnection(string nameOrConnectionString)
{
return new NpgsqlConnection(nameOrConnectionString);
}
DbConnection IDbConnectionFactory.CreateConnection(string nameOrConnectionString)
{
return CreateConnection(nameOrConnectionString);
}
DbProviderFactory IDbProviderFactoryResolver.ResolveProviderFactory(DbConnection connection)
{
return new LocalPgProviderFactory();
}
}
public class LocalPgProviderFactory : DbProviderFactory
{
public override DbConnectionStringBuilder CreateConnectionStringBuilder()
{
return new NpgsqlConnectionStringBuilder(ConnectionString);
}
public override DbConnection CreateConnection()
{
return new NpgsqlConnection(ConnectionString);
}
}
}
}
The strange thing is that I create a new connection using Npgsql but when I'm executing if (!db.Database.Exists()) it try to create a connection using SqlServer provider. It tell me that it doesn't know the "port" attribute of the connection string because sql server haven't this attribute.
I'm thinking that it is looking for the default provider factory into the web.config file but not finding it, it set sql server as default provider.
I would like to set Npgsql as default provider without using a config file at all.
Npgsql add the support to delete or create the database from the 2.2.0 version (now is in beta 1)

Set Entity Framework connection string at runtime

I have generated entity model from AdventureWorks database; now I want to delete the connection string in app.config and set it at runtime. In the Model1.Context.cs file I have chnaged the constructor to
public AdventureWorksEntities(string str)
: base("name=AdventureWorksEntities")
{
this.Database.Connection.ConnectionString = str;
}
and in the program.cs file
EntityConnectionStringBuilder ecsb = new EntityConnectionStringBuilder();
ecsb.Metadata = #"res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl";
ecsb.Provider = #"System.Data.SqlClient";
ecsb.ProviderConnectionString =
#"data source=.\sqlexpress;initial catalog=AdventureWorks;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework";
using (var ent = new AdventureWorksEntities(ecsb.ConnectionString))
{
Console.WriteLine(ent.Database.Connection.ConnectionString);
var add = ent.Addresses;
foreach (var ad in add)
{
Console.WriteLine(ad.City);
}
}
Console.ReadKey();
Now it says metadata keyword not found. How to set connectionstring for entityframework at runtime?
This is an example using standard .aspx login information to set the UserID and Password information in the connection string. No connection string settings are stored in the web.config or app.config file.
Modify the Model.Designer.cs page as follows:
public partial class Entities : ObjectContext
{
#region Constructors
public static string getConStrSQL(string UID,string PWD)
{
string connectionString = new System.Data.EntityClient.EntityConnectionStringBuilder
{
Metadata = "res://*",
Provider = "System.Data.SqlClient",
ProviderConnectionString = new System.Data.SqlClient.SqlConnectionStringBuilder
{
InitialCatalog = "your_database_name",
DataSource = "your_server",
IntegratedSecurity = false,
UserID = UID,
Password = PWD,
}.ConnectionString
}.ConnectionString;
return connectionString;
}
/// <summary>
/// Initialize a new Entities object.
/// </summary>
public Entities(string UID,string PWD)
: base(getConStrSQL(UID,PWD), "Entities")
{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
......
Then in your code behind page:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Mvc;
using System.Web.Security;
public partial class views_html_form : System.Web.UI.Page
{
public void Page_Load()
{
if (currentUser() == null)
{
HttpContext.Current.Response.Redirect("~/login.aspx");
}
}
public static MembershipUser currentUser()
{
MembershipUser currentUser = Membership.GetUser();
return currentUser;
}
public static string UID()
{
string UID = currentUser().UserName;
return UID;
}
public static string PWD()
{
string PWD = currentUser().GetPassword();
return PWD;
}
public static void SelectRecord()
{
YourModel.Entities db = new YourModel.Entities(UID(), PWD());
var query = from rows in db.Table_Name orderby rows.ID select rows;
.....
That's it. No messing around with .config files. Alternatively you could send a database name, for example, as a parameter in the same way.
I'd go with something like:
public AdventureWorksEntities(string server, string databaseName, string user, string password)
:base(new System.Data.EntityClient.EntityConnectionStringBuilder
{
Metadata = "res://*",
Provider = "System.Data.SqlClient",
ProviderConnectionString = new System.Data.SqlClient.SqlConnectionStringBuilder
{
InitialCatalog = databaseName,
DataSource = server,
IntegratedSecurity = false,
UserID = user,
Password = password,
}.ConnectionString
}.ConnectionString)
{
}

Categories