nhibernate logs sql for postgres but not for sql server - sql-server

I'm new to nhibernate (but used hibernate for java before).
I built a session factory for our sql server database (sql server enterprise edition 8)
ISessionFactory factory2 = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(#"user id=xx; password=xxx;server=xxx;initial catalog=xxx")
.ShowSql()
)
.Mappings(m => m.FluentMappings
.AddFromAssemblyOf<Program>())
.ExposeConfiguration(cfg => new SchemaValidator(cfg).Validate())
.BuildSessionFactory();
So I use the ShowSql() method to log the queries to the console.
In my programm I load / create two objects and want to persist them and then do a update on a column:
using (var session = sf.OpenSession())
{
session.FlushMode = FlushMode.Always;
using (var ta = session.BeginTransaction())
{
Console.ReadKey();
PMA pm = session.CreateCriteria<PMA>()
.Add(Restrictions.Eq("Name", "HANSER")).List<PMA>().FirstOrDefault();
if (pm == null)
{
pm = new PMA();
pm.Prio = "1";
pm.Name = "HANSER";
pm.Datum = DateTime.Now;
session.Save(pm);
}
Clip clip = new Clip();
clip.PMA = pm;
clip.sys_created = DateTime.Now;
clip.sys_name = "system name";
clip.Title = "Test";
session.Save(clip);
Console.ReadKey();
clip.Title = "PETERSEN";
session.SaveOrUpdate(clip);
session.Transaction.Commit();
session.Flush();
session.Dispose();
Console.ReadKey();
}
}
The first insert for the pm object will be logged on the console, but the other insert and the update for the clip object don't appear in the console. When I look in the database, I see there is everything right, everything will be inserted and updated. But I want to see the query. I try to set flush mode to always and make a session.Flush() to the session at the end and then a session.Dispose(), but nothing changes.
When I use postgres (only change the sessionfactory), I see all query logs.
How can I let nhibernate log all queries for sql server ?

When using ADO.NET batching (on by default in SQL Server, which supports it), DML queries are not logged to the console.

Related

IdentityServer4 Sample with ASP Identity with real SQL Server

I have been struggling to get the final SAMPLE (ASP.Net, EF Core, SQL) to work against a real SQL Server. Every sample I can find does not use real SQL they always opt for in-memory data store
I changed the connection string
"Data Source=.;Initial Catalog=IS4;Integrated Security=True;"
and ran
dotnet ef database update -c ApplicationDbContext
This created me a SQL database with 25 tables.
I tweaked Startup.cs to change
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
and b.UseSqlite to b.UseSqlServer
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = b =>
b.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
})
// this adds the operational data from DB (codes, tokens, consents)
.AddOperationalStore(options =>
{
options.ConfigureDbContext = b =>
b.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
// this enables automatic token cleanup. this is optional.
options.EnableTokenCleanup = true;
// options.TokenCleanupInterval = 15;
});
I ran the server with "/seed" on the command line but the Seed functionality doesn't work
First it complains CLIENT can't have a NULL ID when it calls SaveChanges(). If I change the code to add the ID
if (!context.Clients.Any())
{
Console.WriteLine("Clients being populated");
int i = 1;
foreach (var client in Config.GetClients().ToList())
{
var x = client.ToEntity();
x.Id = i++;
context.Clients.Add(x);
}
context.SaveChanges();
}
else
{
Console.WriteLine("Clients already populated");
}
I then get
"Cannot insert the value NULL into column 'Id', table 'IS4.dbo.ClientGrantTypes".
When I watch the video's it says it can be migrated from SQLite to full SQL simply by changing the connection string which is obviously not true, given all the other changes I have done, so I must be doing (or missing) something else.
Any thoughts?
Could it be that all the tables with an "Id INT" column should all be IDENTITY columns and they are not!
I checked the migrations code and it has
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "ApiResources",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Description = table.Column<string>(maxLength: 1000, nullable: true),
DisplayName = table.Column<string>(maxLength: 200, nullable: true),
I am guessing
.Annotation("Sqlite:Autoincrement", true),
doesn't work with full SQL and therefore all the tables need identity properties setting.
Interestingly if you run the other template to add the AdminUI
dotnet new is4admin
It seems to add a couple of SQL scripts
CREATE TABLE "Clients" (
"Id" INTEGER NOT NULL CONSTRAINT "PK_Clients" PRIMARY KEY AUTOINCREMENT,
"AbsoluteRefreshTokenLifetime" INTEGER NOT NULL,
"AccessTokenLifetime" INTEGER NOT NULL,
which does make them identity columns.
I was faced with this issue today and did a couple of searches online and stumbled upon this https://entityframeworkcore.com/knowledge-base/46587067/ef-core---do-sqlserver-migrations-apply-to-sqlite-
The link pointed out to switch the annotation portion in the migration class UP method after
Id = table.Column(nullable: false)
from
.Annotation("Sqlite:Autoincrement", true);
to
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn)
And you will need to import
using Microsoft.EntityFrameworkCore.Metadata;
Then you build, and the migration will be successful.
To resolve this particular issue I used SSMS.
right click on table
select script to drop and create
add IDENTITY after the NOT NULL
Execute
However you are correct, it is using sqlite annotations in the sql file and in the migrations.
To fully resolve this issue, you need to create an implementation of all 3 necessary database contexts: identity, persisted grant, and configuration.
That requires an implementation of design time factories for each of those contexts as well.
Then you can run add-migration in the package manager console for each of those contexts, and then run update database, or run the application with the migrate function when seeding.
So to recap:
Create implementations for the 3 db contexts
Create Design time factory implementations for those db contexts
Add the migrations
Update the database with those migrations

copy database structure from sql server to other

I want to copy a database to a sql server to another, but i just want to copy structure (views, stored procedures, tables, fields, indexes, etc), no rows.
I tried to generate a script from sql server management but the script is very verbose (task menu > create as)
Follow Below steps for generate script :
Right Click on Database
Select task
Select Generate Script from Task
Follow the steps
Finally finish for complete this process
You can either use the SQL Server Management Object API (see task "creating, altering and removing databases"):
C# Code for generate sql script :
public string GenerateScript()
{
var sb = new StringBuilder();
var srv= new Server(#"Your Database Server Name");
var db= server.Databases["Your Database name"];
var scrpt = new Scripter(srv);
scrpt.Options.ScriptDrops = false;
var obj= new Urn[1];
foreach (Table tbl in db.Tables)
{
obj[0] = tbl.Urn;
if (tbl.IsSystemObject == false)
{
StringCollection sc = scripter.Script(obj);
foreach (var st in sc)
{
sb.Append(st);
}
}
}
return sb.ToString();
}
You case use Copy database wizard
Some limitations of the it are :
1.The Copy Database Wizard is not available in the Express edition.
1.The Copy Database Wizard cannot be used to copy or move databases that:
Are System.
Are marked for replication.
Are marked Inaccessible, Loading, Offline, Recovering, Suspect, or in Emergency Mode.
Have data or log files stored in Microsoft Azure storage.

SQL Server 2008 R2 & Windows Forms Application

I created a local database and a windows form. In the windows form, in the server explorer, I added this database's connection. Now, how can I begin querying it using LINQ-to-SQL?
Have you set up a DataContext ? That is the typical object standing between your LINQ queries and the database connection.
Sample code from the link above:
// DataContext takes a connection string.
DataContext db = new DataContext(#"c:\Northwnd.mdf");
// Get a typed table to run queries.
Table<Customer> Customers = db.GetTable<Customer>();
// Query for customers from London.
var query =
from cust in Customers
where cust.City == "London"
select cust;
foreach (var cust in query)
Console.WriteLine("id = {0}, City = {1}", cust.CustomerID, cust.City);

Problems deleting data from database

I am using Hibernate to access my database. I would like to delete a set of fields on function of a criteria. My database is PostgreSQL and my Java code is:
public void deleteAttr(String parameter){
Configuration cfg = new Configuration();
cfg.configure(resource.getString("hibernate_config_file"));
SessionFactory sessionFactory = cfg.buildSessionFactory();
session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
tx.begin();
String sql = "delete from attribute where timestamp > to_date('"+parameter+"','YYYY-MM-DD')"
session.createSQLQuery(sql);
tx.commit();
}
The method runs, but it doesn't delete data from database. I have also checked the sql sentence in PgAdmin and it works, but not in code. Why? Does someone help me?
Thanks in advance!
It's because you're creating a query, but you don't execute it:
String sql = "delete from attribute where timestamp > to_date('"+parameter+"','YYYY-MM-DD')"
Query query = session.createSQLQuery(sql);
query.executeUpdate();
You should really use bound named parameters rather than string concatenation to pass parameters in your query: it's usually more efficient, it' much more robust, but above all, it doesn't open the door to SQL injection attacks.

Is there an alternative of using a VBScript for enabling FileStream after SQL Server installation?

To use Filestream on a DB 3 steps must be done:
1) enable it a server/instance level
2) enable it (sp_configure) at DB level
3) create a varbinary(max) field that supports filestream
(2) and (3) are done easily with T-SQL
(1) is doable manually from SQL Server Configuration Manager, basically what I need is to check all the 3 checkboxes:
(source: sql-server-performance.com)
but how is it possible to automize it?
I found this artcile "Enabling filestream usin a VBScript", is there another way to do it than using VBScripts? May be something that is possible to do only with 2008R2?
In case it VBScript is the only solution, which are the possible downsides?
The only way other than clicking in the Configuration Manager is via WMI (which is what the VBScript does). If you don't like VB, here's how I've been configuring it from C# (note that the code needs to run with admin privileges (elevated)):
private ManagementObject GetFilestreamManagementObject(string machineName, string instanceName)
{
string managementPath = string.Format(#"\\{0}\root\Microsoft\SqlServer\ComputerManagement10", machineName);
ManagementScope managementScope = new ManagementScope(managementPath);
managementScope.Connect();
SelectQuery query = new SelectQuery("FilestreamSettings", string.Format("InstanceName='{0}'", instanceName));
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(managementScope, query))
{
ManagementObjectCollection moc = searcher.Get();
if (1 != moc.Count)
{
string exceptionText = String.Format("Expected single instance of FilestreamSettings WMI object, found {0}.", moc.Count);
throw new FilestreamConfigurationException(exceptionText);
}
ManagementObjectCollection.ManagementObjectEnumerator enumerator = moc.GetEnumerator();
if (false == enumerator.MoveNext())
{
throw new FilestreamConfigurationException("Couldn't move ManagementObjectEnumerator to the first entry.");
}
return (ManagementObject)enumerator.Current;
}
}
private void EnableFilestream(int accessLevel)
{
ManagementObject filestreamSettingsObject = GetFilestreamManagementObject("myMachine", "MSSQLSERVER");
ManagementBaseObject methodArgs = filestreamSettingsObject.GetMethodParameters("EnableFilestream");
methodArgs["AccessLevel"] = accessLevel;
methodArgs["ShareName"] = ""; //default
ManagementBaseObject returnObject = filestreamSettingsObject.InvokeMethod("EnableFilestream", methodArgs, null);
if (returnObject == null)
{
throw new FilestreamConfigurationException("Result of calling filestreamSettingsObject.InvokeMethod(\"EnableFilestream\", methodArgs, null)" is null);
}
uint returnValue = (uint)returnObject.GetPropertyValue("ReturnValue");
const uint errorSuccessRestartRequired = 0x80070BC3;
if (returnValue != 0 && returnValue != errorSuccessRestartRequired)
{
Win32Exception win32Exception = new Win32Exception((int)returnValue);
string exceptionText =
string.Format("'EnableFilestream' method returned {0}: {1}", returnValue, win32Exception.Message);
throw new FilestreamConfigurationException(exceptionText);
}
}
Just run this.
USE master
Go
EXEC sp_configure 'show advanced options'
GO
EXEC sp_configure filestream_access_level, 3
GO
EXEC sp_filestream_configure
#enable_level = 3
, #share_name = N'FS';
GO
RECONFIGURE WITH OVERRIDE
GO
More on this
http://www.mssqltips.com/tip.asp?tip=1489
0 = disabled (this is the default)
1 = enabled only for T-SQL access
2 = enabled for T-SQL access and local
file system access
3 = enabled for T-SQL access, local
file system access, and remote file
system access
You can store the script in a stored procedure and call it from your application or anywhere you want.
Here're links on this topic
http://www.mssqltips.com/tip.asp?tip=1838
Link
http://technet.microsoft.com/en-us/library/cc645923.aspx
http://www.sql-server-performance.com/articles/dba/Configure_Filestream_in_SQL_Server_2008_p1.aspx
EDIT
Answer to your comment.
Here's what I call step 2
CREATE DATABASE Archive
ON
PRIMARY ( NAME = Arch1,
FILENAME = 'c:\data\archdat1.mdf'),
FILEGROUP FileStreamGroup1 CONTAINS FILESTREAM( NAME = Arch3,
FILENAME = 'c:\data\filestream1')
LOG ON ( NAME = Archlog1,
FILENAME = 'c:\data\archlog1.ldf')
GO
http://technet.microsoft.com/en-us/library/cc645585.aspx
Check link for all steps
Filestream in Sql Server 2008 Express
Good Luck!
Pawel's solution worked great for us. We were seeing about a 50% failure rate using the VBS -- haven't seen a failure yet with Pawel's approach. Unlike Greg's results, it has worked great for us against a local system. Actually, that's all we have tried it with.
We did have to make a couple of adjustments to Pawel's code. The line
throw new FilestreamConfigurationException("Result of calling filestreamSettingsObject.InvokeMethod(\"EnableFilestream\", methodArgs, null)" is null);
has the final quote character out of place. It should be after the "is null", right before the ");".
We also had to make sure we got the instanceName built correctly. For example, if we had "mymachine\myinstance", we had to make sure that "instanceName=myinstance" and not the full name. Further, if we had "mymachine" (the default instance), we had to have "instanceName=MSSQLSERVER". Maybe that is Greg's problem -- when we had the instanceName set to the wrong thing, we got the same results Greg reports.

Resources