Raven db: creating a new database - ravendb

I am new to raven db. I have read the API and try to create a database . It has something like EnsureDatabaseExists function which creates the database if it does not exist. It actually uses DocumentDatabase type to create that database. I use it and it creates the database but I want to use this object directly so that using this object I can directly work with documents. Am i doing right? Or can there be any better approach then this to work with documents.Thank you.

I think you're confusing the database document and querying documents.
The database document is a document on the default database, which just represent a database in RavenDB which is not the default database. It stores some data like the database name and location. You, as a consumer of ravendb as nothing to do with this document. And this has nothing to do with querying any other documents.
Look here in order to learn how to query ravendb for documents. In order to query a specific database, if you work just with that database than you better just specify the database name in the connection string. If you work against multiy databases at once, you can specify the database name that you want when you open a session, store.OpenSession("database-name").

Three methods are available on store.DatabaseCommands.GlobalAdmin.
GetDatabaseNames: lists database names
EnsureDatabaseExists: creates database if it does not exists
CreateDatabase: creates database
Note that DocumentStore.Initialize() already ensures that the database is created. You can pass a boolean false to avoid this behavior.
// init store object, you pass the service URL + the database name
var store = new DocumentStore("http://localhost:8001/databases/MyNewDataBase");
store.Initialize(false);
// most simple thing is:
var dbName = store.DefaultDatabase;
store.DatabaseCommands.GlobalAdmin.EnsureDatabaseExists(dbName);
If you want to check without creating:
// there is a method to list the database names
bool exists = false;
for (int i = 0; i < int.MaxValue; i++)
{
var names = store.DatabaseCommands.GlobalAdmin.GetDatabaseNames(100, i * 100);
if (names.Contains(dbName))
{
exists = true;
break;
}
if (names.Length < 100)
{
// no more databases
break;
}
}
if (exists)
{
// database exists, do something
}
Reference: https://ravendb.net/docs/article-page/3.5/Csharp/client-api/commands/how-to/create-delete-database

Related

Create table Routine definition

I've been using this table INFORMATION_SCHEMA.ROUTINES which has the routine definition for procs and functions, i was wondering if there is a similar table for create table and create view routines.
I would just skip using INFORMATION_SCHEMA.ROUTINES entirely. Instead look at sys.sql_modules. It has the ddl for everything you are looking for except tables. But my question is why do you need to find the ddl for all these things?
You can use sys.sql_modules to find the definition of views. For tables, one option is SMO objects. The C# example below returns the DDL for a table in the listed database. This will require references to the Microsoft.SqlServer.Management.Sdk.Sfc, Microsoft.SqlServer.Smo, and Microsoft.SqlServer.ConnectionInfo namespaces. System.Collections.Specialized is also used, but only for StringCollection in this example. This can be filtered using the Name property of the Table class as noted below.
//set source server and database using SMO objects
Server srv = new Server(#"YourServer");
//for Windows Authentication
srv.ConnectionContext.LoginSecure = true;
srv.ConnectionContext.StatementTimeout = 600;
Database db = srv.Databases["YourDatabase"];
//configure Scripter for DDL
Scripter script = new Scripter(srv);
ScriptingOptions scriptOpt = new ScriptingOptions();
//this can changed to views, stored procedures, or other objects
foreach (Table t in db.Tables)
{
//check for system objects
//use t.Name to check table name if needed
if (!t.IsSystemObject)
{
StringCollection sc = t.Script(scriptOpt);
foreach (string s in sc)
{
//DDL is here, it can accessed/used as needed
Console.WriteLine(s);
}
}
}

Entity Framework Core GetOrAdd Method

I'm working on a post method that should have a really good performance.
I have a value in the request body that will look in the database for the row that is connected with that value and return it and add it as a foreign key.
So how it is now:
Look in the database and check if the data already exists
If no add it to the database
Look that added or already existing data in the database and join it to the entity
So now there are 3 calls to the database
I was wondering if there is some kind of GetOrAdd method that will connect the table to my data if it exists and if it not exists add it to the database so it will most of the time only have 1 call to the database instead of always 3 calls
Please read the following doc
Here is an "Insert or Update" pattern:
public void InsertOrUpdate(Blog blog)
{
using (var context = new BloggingContext())
{
context.Entry(blog).State = blog.BlogId == 0 ?
EntityState.Added :
EntityState.Modified;
context.SaveChanges();
}
}
Of note, once you hit SaveChanges() you can expect your in memory object (blog, in this case) to be the same object that is stored in the database, and would not have to make a 3rd call to retrieve it again. EF Core will update the Primary Key with the actual persisted Id.
using (var context = new BloggingContext())
{
var blog = new Blog {Id = 1, Url = "blablabla" };
context.Blogs.Update(blog);
await context.SaveChangesAsync();
}
If a reachable entity has its primary key value set then it will be tracked in the Microsoft.EntityFrameworkCore.EntityState.Modified state. If the primary key value is not set then it will be tracked in the Microsoft.EntityFrameworkCore.EntityState.Add state.
This comment is from Entity Framework Core's Update method. You just need to call Update method if entity is exist in Database it will be updated otherwise will be created as new record.

TSQL | Create Database

I have two databases on my local. I wish to use tsql to script out one of the two databases in its entirety (schema only) and save it in one .sql script. Is this possible for SQL 2012? And if so, how may I go about doing it? I am using GUI to do this right now but want to use tsql query if possible. I can't use any 3rd party tools.
Thank you
UPDATE: I am using the RIGHT CLICK > GENERATE script method right now. I want to avoid that and find a way to generate the database generation tsql script by some way other than using SSMS GUI. Also, I want to script the entire database and not just tables.
You can do it in the following 2 ways.
Use Powershell.
Use the SMO classes, the Scripter class in particular. The GUI Tools are wrappers around this class.
Here's the solution for #1.
Using Powershell to Generate Table-Creation Scripts. By Robert Sheldon on simple-talk.com
Here's a solution for #2.
See this MSDN Example scripting all tables in a database with SMO.
Relevant code below. Change the database name and other details as appropriate.
//Connect to the local, default instance of SQL Server.
{
Server srv = default(Server);
srv = new Server();
//Reference the AdventureWorks database.
Database db = default(Database);
db = srv.Databases("AdventureWorks");
//Define a Scripter object and set the required scripting options.
Scripter scrp = default(Scripter);
scrp = new Scripter(srv);
scrp.Options.ScriptDrops = false;
scrp.Options.WithDependencies = true;
//Iterate through the tables in database and script each one. Display the script.
//Note that the StringCollection type needs the System.Collections.Specialized namespace to be included.
Table tb = default(Table);
Urn[] smoObjects = new Urn[2];
foreach ( tb in db.Tables) {
smoObjects = new Urn[1];
smoObjects(0) = tb.Urn;
if (tb.IsSystemObject == false) {
StringCollection sc = default(StringCollection);
sc = scrp.Script(smoObjects);
string st = null;
foreach ( st in sc) {
Console.WriteLine(st);
}
}
}
}
If you want to script out ALL the DB objects, and not just tables, take a look at the powershell script in this page where it says "Full Script". It takes care of table and relationship dependencies also.

Unit testing NHibernate application with SQLite: it writes to the database but cannot read back

I have an application using NHibernate that is already deployed and working properly, and I'm re-factoring the unit tests to use SQLite for improved performance, and to keep unit test data out of the "real" database.
I have a simple test that creates an Calendar entity, saves it, then tries to read it back and verifies that it's the same object. The write works, but the subsequent select to read it back returns 0 records. A Calendar has a GUID as a primary key, and I understand that requires an extra parameter on the SQLite connection string. This is my connection string:
data source=:memory:;Version=3;New=true;Pooling=true;Max Pool Size=1;BinaryGuid=False
Through the logged SQL statements coming from NHibernate, I see the inserts to write the entity and its dependencies, then the subsequent select statement. It all looks good, but nothing is selected. If I use a file database instead of an in-memory database, I can open up the table in Visual Studio's Server Explorer, and I see the correct data in the tables. If I write a query to try selecting the record, like so:
SELECT CalendarID, Name, Description
FROM dbo_Calendars
WHERE (CalendarID = 'a9cd9820-1694-4645-88d4-f682c5a6b9cc')
it also fails to select anything. I think it's an issue with GUID handling, but I'm flummoxed.
Update
Here's what the test case looks like:
[Test]
public void SaveAndLoadCalendar()
{
Guid calId;
DAOFactory factory = (DAOFactory)DAOFactory;
ISession s = factory.SessionManager.CurrentSession;
using (var tx = s.BeginTransaction())
{
Calendar cal = new Calendar("Test Calendar", CalendarType.Test);
cal.Active = true;
cal.Browsable = true;
s.Save(cal);
tx.Commit();
calId = cal.ID;
}
Logger.InfoFormat("Calendar ID is {0} ", calId);
s.Clear();
using (var tx2 = s.BeginTransaction())
{
Calendar cal = s.Get<Calendar>(calId);
Assert.IsNotNull(cal, "Could not retrieve saved calendar");
Assert.AreEqual("Test Calendar", cal.Name, "Saved calendar not equal to original calendar");
}
}
I would guess that the transaction handling could be the problem.
So maybe the transaction inserting the record is not yet committed and so the (different) transaction performing the select does not yet see the new data - so the select returns nothing.
I figured it out, and the problem isn't NHibernate or SQLite, it's me. Each Calendar has an associated Theme. In our production database, these are manually entered, and expected to exist in advance. Now that I'm using SQLite for testing, I'm starting with an empty database, and this reference data isn't pre-populated. NHibernate's Select statement to fetch the Calendar uses an inner join on the Themes table, and with nothing in that table, the select will return empty. D'oh.
After updating my test setup code to save the default theme, the test passes.

NHibernate - How do I change schemas during run time?

I'm using NHibernate to connect to an ERP database on our DB2 server. We have a test schema and a production schema. Both schemas have the same table structure underneath. For testing, I would like to use the same mapping classes but point NHibernate to the test environment when needed and then back when in production. Please keep in mind that we have many production schemas and each production schema has an equivalent test schema.
I know that my XML mapping file has a schema property inside it, but since it's in XML, it's not like I can change it via a compiler directive or change the schema property based on a config file.
Any ideas?
Thank You.
No need to specify schema in the mappings: there's a SessionFactory-level setting called default_schema. However, you can't change it at runtime, as NHibernate pregenerates and/or caches SQL queries, including the schema part.
To get what I wanted, I had to use NHibernate.Mapping.Attributes.
[NHibernate.Mapping.Attributes.Class(0, Table = “MyTable”, Schema = MySchemaConfiguration.MySchema)]
In this way, I can create a class like MySchemaConfiguration and have a property inside of it like MySchema. I can either set the property's value via a compiler directive or get it through a configuration file. This way I only have to change the schema in one place and it will be reflected throughout all of the other mappings.
I have found following link that actually fixes the problem.
How to set database schema for namespace in nhibernate
The sample code could be
cfg.ClassMappings.Where(cm => cm.Table.Schema == "SchemaName")
.ForEach(cm => cm.Table.Schema = "AnotherSchemaName");
This should happen before you initialize your own data service class.
#Brian, I tried NHibernate.Mapping.Attributes, the attribute value you put inside should be a constant. So it could not be updated during run time. How could you have set the property's value using a parameter value in configuration file?
The code to fix HBM XML resources.
// This is how you get all the hbm resource names.
private static IList<string> GetAllHbmXmlResourceNames(Assembly assembly)
{
var result = new List<string>();
foreach (var resource in assembly.GetManifestResourceNames())
{
if (resource.EndsWith(".hbm.xml"))
{
result.Add(resource);
}
}
return result;
}
// This is how you get the stream for each resource.
Assembly.Load(assembly).GetManifestResourceStream(name)
// What you need to do next is to fix schema name in this stream
// Replacing schema name.
private Stream FixSchemaNameInStream(Stream stream)
{
StreamReader strStream = new StreamReader(stream);
string strCfg = strStream.ReadToEnd();
strCfg = strCfg.Replace(string.Format("schema=\"{0}\"" , originalSchemaName), string.Format("schema=\"{0}\"" , newSchemaName));
return new MemoryStream(Encoding.ASCII.GetBytes(strCfg));
}
Take a look at SchemaUpdate.
http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/28/create-and-update-database-schema.aspx