SqlDependency not working with Entity Framework - caching

I have an issue when trying to start the SqlDependency.
The error informs me: Keyword not supported: 'metadata'.
The connectionstring is the following when retrieved from the immediate window right before it crashes.
?objectContext.Connection.ConnectionString
"metadata=res://*/YeagerTech.csdl|res://*/YeagerTech.ssdl|res://*/YeagerTech.msl;provider=System.Data.SqlClient;provider connection string=\"data source=Bill-PC;initial catalog=YeagerTech;integrated security=True;multipleactiveresultsets=True;App=EntityFramework\""
Here is the code. It crashes on the Start method. Apparently, it doesn't think the EF connectionstring is valid. Any idea of how I can correctly use this?
YeagerTechEntities dbContext = new YeagerTechEntities();
ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
SqlDependency.Start(objectContext.Connection.ConnectionString);

Because EF connection string is not valid for SqlDependency. It works only with EntityConnection but SqlDependency uses SqlConnection. So you must either use direct connection string in your dbContext or extract database connection string from entity connection.
Either:
var connectionString = dbContext.Database.Connection.ConnectionString;
Or
var connectionString = ((EnityConnection)objectContext.Connection).StoreConnection.ConnectionString;
Anyway EF doesn't play very well with SqlDependency. SqlDependency expects that you write SQL queries yourselves and have them under your control.

Actually, the code snippet that I got it to work is the following:
YeagerTechEntities dbContext = new YeagerTechEntities();
ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
Application["dbContext"] = dbContext;
objectContext.Connection.ConnectionString =
ConfigurationManager.ConnectionStrings["YeagerTechEntities"].ConnectionString;
SqlDependency.Start(((System.Data.EntityClient.EntityConnection)objectContext.Connection)
.StoreConnection.ConnectionString);
YeagerTechEntities is the EF connectionstring.

Related

Oracle connection strings in blazor app with ef code

I have a Blazor server project with Oracle Database. When I try to use the connection
"ConnectionStrings": {
"GTravelDbConnection": "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVER=dedicated)(SERVICE_NAME=XE)));User Id=GTRAVEL; Password=cteam;"
in appsettings.json and use in program.cs the following code
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("GTravelDbConnection");
builder.Services.AddDbContext<GTravelDbContext>(
options => options.UseOracle(connectionString)
);
I get the error
No database provider has been configured for this DbContext. A provider can be configured by overriding the 'DbContext.OnConfiguring' method or by using 'AddDbContext' on the application service provider. If 'AddDbContext' is used, then also ensure that your DbContext type accepts a DbContextOptions object in its constructor and passes it to the base constructor for DbContext.
The same connection string if used from dbcontext class
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseOracle("Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVER=dedicated)(SERVICE_NAME=XE)));User Id=GTRAVEL; Password=cteam;");
}
}
works with no problem.
I would be obliged if someone could help me.
The problem was that I was trying to use a scoped service without creating a scope. When I used the following code in program.cs
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("GTravelDbConnection");
builder.Services.AddDbContext<GTravelDbContext>(
options => options.UseOracle(connectionString)
);
builder.Services.AddScoped<ICustomerService, CustomerService>();
using (var serviceScope = app.Services.CreateScope())
{
var services = serviceScope.ServiceProvider;
var customerService = services.GetRequiredService<ICustomerService>();
}
it all worked perfectly.
Thank you

Dapper with MVCMiniProfiler

I am wanting to use the MVCMiniProfiler with Dapper. Is this possible beyond wrapping the "Query" call from dapper in "Using Profiler.Step" block?
I have this basic Dapper call:
Dim comments As List(Of Comment)
Using conn = New SqlConnection(ConnectionString)
conn.Open()
comments = conn.Query(Of Comment)("SELECT * from comments where userid = #userid", New With {.userid= 1})
End Using
The MiniProfiler examples show this
Private Shared _sqlConnection As SqlConnection
Public Shared Function GetOpenConnection() As DbConnection
If _sqlConnection Is Nothing Then
_sqlConnection = New SqlConnection("connection string")
End If
' wrap the connection with a profiling connection that tracks timings
Return MvcMiniProfiler.Data.ProfiledDbConnection.[Get](_sqlConnection, MiniProfiler.Current)
End Function
Where I am stuck is in the implementation of the "Get" on the ProfiledDbConnection. Is it possible to use ProfiledDbConnection while using Dapper?
Good catch, the documentation is out of date, just updated it:
Use something like:
return MiniProfiler.Current != null ?
new MvcMiniProfiler.Data.ProfiledDbConnection(cnn, MiniProfiler.Current) :
cnn;
I killed the factory cause I wanted people to be able to inherit off ProfiledDbConnection and statics can not be virtualized.

MVC Mini Profiler with Entity Framework: How to Get Connection

I would like to use MVC Mini Profiler for Entity Framework Connection. The way I did it is like this:
public static XXXXX.DAL.BO.XXXXXEntities GetEntityConnection()
{
var conn = ProfiledDbConnection.Get(new EntityConnection(ConfigurationManager.ConnectionStrings["XXXXXEntities"].ConnectionString));
return ObjectContextUtils.CreateObjectContext<XXXXX.DAL.BO.XXXXXEntities>(conn);
}
So the following line is to get the Context for the rest of the code:
XXXXX.DAL.BO.XXXXXEntities ctx = GetEntityConnection();
When I attempted to view this site on a browser, however, the WebDev.WebServer40.exe crashed.
Does anyone have any idea why?
Thanks heaps.
P.S.
Previously it was
XXXXX.DAL.BO.XXXXXEntities ctx = new XXXXX.DAL.BO.XXXXXEntities();
and it worked fine.
If you are able to use the v3.0.10 nuget for EF6, then all you need to do to hook up Entity Framework is
protected void Application_Start()
{
MiniProfilerEF6.Initialize();
}
Using EF 5 or earlier (with the corresponding nuget package) would require you to generate an EFProfiledDbConnection as Anirudh wrote in his answer:
var conn = new EFProfiledDbConnection(GetConnection(), MiniProfiler.Current);
return ObjectContextUtils.CreateObjectContext<MyModel>(conn);
try initialising your connection to :
connection = new EFProfiledDbConnection( new EntityConnection(ConfigurationManager.ConnectionStrings["XXXXXEntities"].ConnectionString),
MiniProfiler.Current);
works for me.

Oracle and Transaction naming

I've been programing with SQL Server and C# for quite some time and I have some code that I need to change to work with Oracle:
SqlConnection connection = (SqlConnection)CreateDBConnection();
IDbTransaction transaction = connection.BeginTransaction(level, "name");
The problem is: if I use OracleConnection instead of SqlConnection there is no way to specify a name for my transaction. I know that the syntax in Oracle allows named transactions, but I don't seem to find a way to do it through .net code.
You can not set the transaction name.
But it is possible to specify a name for the SAVEPOINT.
OracleConnection oracleConnection = new OracleConnection((string.Format("Data Source={0};User Id={1};Password={2}", DATABASE, USERNAME, PASSWORD));
oracleConnection.Open();
OracleCommand oracleCommand = oracleConnection.CreateCommand();
oracleConnection.BeginTransaction();
OracleTransaction oracleTransaction = oracleCommand.Transaction;
oracleTransaction.Save("name");
//...
oracleTransaction.Rollback("name");

Creation of Dynamic Entities in MS CRM 4.0

I am trying to create a new contact using Dynamic Entity. The sample i found in CRM SDK had this code.
// Set the properties of the contact using property objects.
StringProperty firstname = new StringProperty();
firstname.Name = "firstname";
firstname.Value = "Jesper";
StringProperty lastname = new StringProperty();
lastname.Name = "lastname";
lastname.Value = "Aaberg";
// Create the DynamicEntity object.
DynamicEntity contactEntity = new DynamicEntity();
// Set the name of the entity type.
contactEntity.Name = EntityName.contact.ToString();
// Set the properties of the contact.
contactEntity.Properties = new Property[] {firstname, lastname};
In my code i have the following implementation.
StringProperty sp_Field1 = new StringProperty("Field1","Value1");
StringProperty sp_Field2 = new StringProperty("Field2","Value1");
CrmService service = new CrmService();
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
// Create the DynamicEntity object.
DynamicEntity contactEntity = new DynamicEntity();
// Set the name of the entity type.
contactEntity.Name = EntityName.contact.ToString();
// Set the properties of the contact.
contactEntity.Properties = new Property[] {sp_Field1,sp_Field2};
I don't see much differences in the code. In the examples i found in the internet i have the same implementation as i found in SDK. But if i run the same i get the following error
CS0029: Cannot implicitly convert type 'Microsoft.Crm.Sdk.StringProperty' to 'Microsoft.Crm.Sdk.PropertyCollection'
I tried created a new variable of type PropertyCollection(one that belongs in mscrm namespace) and added the stringpropertys into that and passed it to the entity.
Microsoft.Crm.Sdk.PropertyCollection propTest = new Microsoft.Crm.Sdk.PropertyCollection();
propTest.Add(sp_SSNNo);
propTest.Add(sp_FirstName);
contactEntity.Properties = new Property[] {propTest};
This gave me the following error
CS0029: Cannot implicitly convert type 'Microsoft.Crm.Sdk.PropertyCollection' to 'Microsoft.Crm.Sdk.Property'
I am sure its a minor typecasting error but i am not able to figure out where the error is. And moreover, even if it was a typecasting error why is it working for all the samples given in the internet and not for me. I tried getting the code sample to run but i am encountering the same conversion error. Please let me know if you need more info on this, any help on this would be appreciated.
Here is an article from Microsoft that makes an attempt to discuss this topic:
http://community.dynamics.com/blogs/cscrmblog/archive/2008/06/23/web-services-amp-dlls-or-what-s-up-with-all-the-duplicate-classes.aspx
This is not a bug that you are running into but more of a difference in design between the way the two assemblies work and what they are designed to do.
If you want to continue to use the Microsoft.Crm.Sdk.dll you should be able to accomplish your goal with the following...
StringProperty sp_Field1 = new StringProperty("Field1","Value1");
StringProperty sp_Field2 = new StringProperty("Field2","Value1");
CrmService service = new CrmService();
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
// Create the DynamicEntity object.
DynamicEntity contactEntity = new DynamicEntity();
// Set the name of the entity type.
contactEntity.Name = EntityName.contact.ToString();
// Set the properties of the contact.
PropertyCollection properties = new PropertyCollection();
properties.Add(sp_Field1);
contactEntity.Properties = properties;
Thanks SaaS Developer, that code is working fine now. One more way of doing it would be to directly add the StringProperty to the entity property collection.
contactEntity.Properties.Add(sp_SSNNo);
Thanks again for replying :)
I believe the issue is that you are referencing the dynamic entity class in the Microsoft.Crm.Sdk assembly. The sample in the SDK is using a reference to the CRM web service. This can get confusing as both assemblies contain many of the same types, however they are different.

Resources