I have a webapi for which I am trying to debug.
I use a generic repository structure so all my entity framework calls are made in a separate class library.
So my web Api post end point effectively just calls service.insert(entity). Where the generic insert is in the separate class library.
Logging is currently setup and working in the api. Now I want to log the insert Sql generated by entity framework in the parent applications text log file (as something strange is going on in the live environment)
How would I go about doing this please?
How to do this depends on what version of Entity Frameework you are using. In EF6 and later it is simple:
using (var context = new DataContext())
{
// log is a log4net logger
context.Database.Log = message => log.Debug(message);
// insert the entity
}
See this blog series for more information - part 3 shows an example of logging to NLog with a command interceptor - and this page for options relating to earlier versions of EF.
Related
I am building a windows service.
I am trying to have miniprofiler, intercept ado.net calls and hand the messages to my application's logging system.
All miniprofiler needs to do is to call a static method Log(string text).
I went through the following post and learned how to intercept ado.net calls:
Using MiniProfiler for direct ADO.net calls
It seems that the only unsolved puzzle is to have miniprofile call my log method. How can I do that?
I went through the site http://miniprofiler.com/, but the documentation is minimal.
In short: this isn't something MiniProfiler is designed to do, because that's not profiling.
However, you lucked out in how MiniProfiler is implemented here. You can implement IDbProfiler yourself that just calls the logger. There are only a handful of methods. Here's MiniProfiler's implementation.
If your implementation just calls your logging method(s), you can re-use all of the ADO.NET bits built for MiniProfiler like this:
IDbProfiler logger = new YourLogger();
var conn = new SqlServerConnection(myConnectionString);
var profiledConn = new ProfiledDbConnection(cnn, logger);
// ...do stuff with profiledConn
In the new ASP.NET Core RC2 template (With no database available at the back-end), when I try to register a user it throws the following error for adding Migrations.
While in the past, it use to generate the database for us without adding initial migration when we run the application. Is there a way to create the database in ASP.NET Core RC2 without Initial Migration?
For testing scenario you can use context.Database.EnsureCreatedAsync() somewhere during startup. Ensure you are using this pattern (for now) and not inject it directly in configure, to avoid issues during startup.
For future reference the code section copied from the MusicStore example application.
using (var serviceScope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var db = serviceScope.ServiceProvider.GetService<MusicStoreContext>();
if (await db.Database.EnsureCreatedAsync())
{
await InsertTestData(serviceProvider);
if (createUsers)
{
await CreateAdminUser(serviceProvider);
}
}
}
because at this point, there is no scope yet. If you later want to apply the migrations you can use context.Database.AsRelational().ApplyMigrations() (GitHub issue)
I have used Glimpse before and really liked it so when this new project came up I went right to it. This time however I am using the EF plugin which is new to me. Further the project is broken up into different layers. Overall glimpse is working and it is just the SQL tab that is not active. Logging is turned on with no errors.
My Solution is like so:
VS 2015
Repository Project EF 6.0.0.0
Glimpse ADO 1.7.3.0
Glimpse Core 1.8.6.0
MVC & WebAPI Project MVC 5.2.3 WebApi
Glimpse ADO 1.7.3.0
Glimpse ASP.Net
Glimpse Core 1.8.6.0
Glimpse EF6 1.6.5
Glimpse MVC 5
So I am creating a manual SQL connection and most likely that is where my mistake is?
In the repository I establish my context like this:
public class PROJDataContext : DbContext, IPROJDataContext
{
public PROJDataContext() : base(PROJConnection, true)
{ }
private static GlimpseDbConnection PROJConnection
{
get
{
//glimpse wrapper
var conxSection = ConfigurationManager.ConnectionStrings["PROJData"];
return new GlimpseDbConnection(new SqlConnection(conxSection.ConnectionString));
}
}
When I fire up the project localhost the SQL tab is disabled. I am assuming this is because the db has not been accessed yet.
I browse to a page that passes request to WebApi. WebApi queries the repository. Data is retrieved from repository and sent back to WebApi which then passes it back to the MVC controller action which then returns a view showing the data.
Glimpse accurately tracks ALL of this except the db portion so any pointers would be greatly appreciated.
Update...when I wrote this up it was EOD Friday. Talking this through with a colleague today I think I realized the problem. My MVC app which has the Glimpse hooks does NOT call SQL instead it calls off to web api and web api calls the repository which has the Glimpse SQL hooks.
I have a C# project with EF code-first approach. The purpose is to do crud operations. My web app will be hosted under IIS under two folders
web app
WCF service
The application will pass user credentials to the WCF service and then to SQL Server database. Code first approach works well in this case.
READ scenario: the data needs to be filtered on the database level, not on application level. So I cannot directly call tables while querying SQL using EF. User will not have read access on the tables but only on views. The SQL views will have responsibility to filter the data and then pass to the service.
The question is how to proceed with EF code first approach in a way that I can leverage the benefits of EF migration s and then map the tables to the SQL views. Can anyone explain how to proceed with this read scenarios and best approach?
Entity Framework doesn't support mapping to Sql views but you can do the following:
Create an entity class that mapping your (sql) view structure.
Add a new empty migration using the add-migration -IgnoreChanges command since you don't want your entities to map to tables.
In this migration you can create (Up method) your Sql view.
It is important to note that you have to indicate the Sql view name in your entity ("view entity?") configuration (mapping) class:
public class FooConfiguration : EntityTypeConfiguration<Foo>
{
public FooConfiguration()
{
ToTable("ViewName");
HasKey(p => p.Id); // You also have to configure a key
}
}
This article from Julie Lerman could be interesting for you: https://msdn.microsoft.com/en-us/magazine/dn519921.aspx
I would like to build a DLL (which should be accessed from a web service and possibly from another application through automation).
Is there any possibility using NHibernate inside this dll (so accessing the dll through automation would work) ?
I am already using NHibernate in a rich client application and it is very handy , but I have to make some changes to the app.config for this. All the other tutorials I see are using NHibernate directly on the web service - and are changing the web.config accordingly.
If you configure NHibernate in code rather than using app.config or web.config you should be able to avoid the problem you describe. For example you could use Fluent NHibernate's Fluent Configuration feature to configure NHibernate and thus avoid use of both web.config and hibernate.cfg.xml, which potentially could cause some trouble as well.
I am currently using this approach in a web app, where the data access layer is in a separate assembly and the web assembly has no reference to NHibernate and needs no modification to web.config, nor is a hibernate.cfg.xml file used.
Here is an example of a Fluent configuration:
sessionFactory = Fluently.Configure()
.Mappings(x => x
.FluentMappings.AddFromAssemblyOf<FooMap>()
.ConventionDiscovery.AddFromAssemblyOf<BarConvention>()
)
.Database(MsSqlConfiguration.MsSql2005.ConnectionString(x => x
.Database("YourDbName")
.Server(#".\SQLEXPRESS")
.TrustedConnection())
.ShowSql())
.BuildSessionFactory();
Update:
The same goal should be possible to achieve using only standard NHibernate, by using their programmatic configuration possibilities. Instead of using the web.config or such to configure your database connection etc. you could pass an IDictionary instance to Configuration.SetProperties() when you create your session factory.
Something like this:
Configuration config = new Configuration();
IDictionary properties = new Hashtable();
properties["hibernate.dialect"] = "NHibernate.Dialect.MsSql2005Dialect";
// more properties here ...
config.SetProperties(properties);
Chapter 3 of the docs has some info about this, but it is a bit on the short side.