Gdy przygotowywałem stronę z projektami i byłem przy ShipBattleChallenge, gdy okazało się, że przed formatowaniem dysku nie zrobiłem backupu bazy danych dla turnieju SBC. Tak – zrobiłem mini programik, który zamiast mnie uruchamia odpowiednie walki botów i loguje przebiegi walk do bazy – Tournament Master :). W związku z tym, że nie jest to kluczowe dla projektu postanowiłem wyłączyć to z solucji. Jednakże po chwili namysłu stwierdziłem, że skoro w dbml’u sa informacje na temat tabel, to może coś da się z tym zrobić… Dziś udało mi się zasiąść do tematu i poszukać co i jak. Okazuje się, że obiekty typu DataContext posiadają metodę CreateDatabase(), która potrafi przywrócić zaimportowane do dbml’a struktury i relacje z bazy. Oczywiście obejmuje to tylko DDL (ang. Data Definition Language), a nie DML. W moim przypadku było to w zupełności wystarczające, gdyż korzystałem z bazy poprzez LINQ to SQL – bardziej dla testów niż z przekonania, ale okazało się to przydatne.

Jak to zrobić? Wystarczy skorzystać z poniższego kawałka kodu:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private static void RestoreDB()
{
	try
	{
		DataClasses1DataContext bd = new DataClasses1DataContext(DbmlTest.Properties.Settings.Default.DbmlTestNewConnectionString);
		if (bd.DatabaseExists())
		{
			Console.WriteLine("Database exists");
			bd.DeleteDatabase();
			Console.WriteLine("Database deleted");
		}
		bd.CreateDatabase();
		Console.WriteLine("Database restored");
	}
	catch (Exception ex)
	{
		Console.WriteLine("Error");
		Console.WriteLine(ex.ToString());
	}
}

Dla porządku dodam, że nie trzeba korzystać z konstruktora wymagającego connection stringa, lecz śmiało można użyć domyślnego. W demie mam zdefiniowane połączenia do dwóch baz, starej i nowej (docelowa baza do odtworzenia), dlatego wybrałem takie rozwiązanie.

Pobierz przykład