अगर यह मैं होता (जब यह मैं होता...):
आप विशेष रूप से डेटाबेस फ़ाइलों को कॉपी करके और उन्हें संलग्न करके काम करने की कोशिश नहीं करना चाहते हैं - ऐसे कारण हैं जो आप चाहते हैं लेकिन मेरा मानना है कि ये नियम के बजाय अपवाद हैं।
तदनुसार आपको डेटाबेस के स्क्रिप्ट निर्माण के लिए क्या करना है यानी डेटाबेस और टेबल बनाने के लिए SQL डीडीएल का उपयोग करना और आपकी स्कीमा में अन्य सभी चीजें।
ऐसा करने के लिए आपको सक्षम करने के लिए आपको सर्वर इंस्टेंस के उचित अधिकार और फिर एक कनेक्शन स्ट्रिंग (जिसे आप शायद सर्वर/इंस्टेंस नाम से अलग कर सकते हैं) की आवश्यकता है।
यहां से:
- क्या कोई डेटाबेस है? अगर इसे नहीं बनाया है।
- यदि कोई डेटाबेस है, तो क्या यह सही स्कीमा संस्करण है? यदि बहुत कम है तो या तो इसे अपडेट करें या उपयोगकर्ता को सलाह दें और इस पर निर्भर करते हुए कि आप चीजों को कैसे काम करना चाहते हैं, इनायत से वापस आएं। यदि बहुत अधिक है तो बस वापस जाएं और सलाह दें कि एप्लिकेशन के एक अद्यतन संस्करण की आवश्यकता है
- सब वैसा ही है जैसा होना चाहिए, जारी रखें।
कोड के दृष्टिकोण से:यह निर्धारित करने की विधि कि क्या कोई डेटाबेस मौजूद है; एक संस्करण तालिका और 0 की संस्करण संख्या के साथ एक मानक "खाली" डेटाबेस बनाने की विधि; उपयुक्त डीडीएल चलाकर स्कीमा को वर्तमान संस्करण तक लाने के तरीके (हम अपने को सी # में एन्कोड करते हैं क्योंकि यह अधिक लचीलापन प्रदान करता है लेकिन आप अनुक्रम में डीडीएल स्क्रिप्ट को समान रूप से चला सकते हैं)।
क्या यह मौजूद है:
public virtual bool Exists()
{
bool exists = false;
string masterConnectionString = this.CreateConnectionString(this.Server, this.FailoverServer, "master");
this.DBConnection.ConnectionString = masterConnectionString;
this.DBConnection.Open();
try
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = this.DBConnection;
cmd.CommandText = "SELECT COUNT(name) FROM sysdatabases WHERE name = @DBName";
cmd.Parameters.AddWithValue("@DBName", this.DBName);
exists = (Convert.ToInt32(cmd.ExecuteScalar()) == 1);
}
finally
{
this.DBConnection.Close();
}
return exists;
}
एक नया डेटाबेस बनाएँ:
public virtual void CreateNew()
{
string createDDL = @"CREATE DATABASE [" + this.DBName + "]";
this.BuildMasterConnectionString();
this.DBConnection.Open();
try
{
this.ExecuteSQLStmt(createDDL, this.DefaultSQLTimeout, null);
}
finally
{
this.DBConnection.Close();
}
createDDL = @"
CREATE TABLE AAASchemaVersion
(
Version int NOT NULL,
DateCreated datetime NOT NULL,
Author nvarchar(30) NOT NULL,
Notes nvarchar(MAX) NULL
);
ALTER TABLE AAASchemaVersion ADD CONSTRAINT PK_Version PRIMARY KEY CLUSTERED
(
Version
);
INSERT INTO AAASchemaVersion
(Version, DateCreated, Author, Notes)
VALUES
(0, GETDATE(), 'James Murphy', 'Empty Database')
";
this.BuildConnectionString();
this.ConnectionString += ";pooling=false";
this.DBConnection.Open();
try
{
this.ExecuteSQLStmt(createDDL, this.DefaultSQLTimeout, null);
}
catch (Exception ex)
{
throw new Exception("Exception while creating / initialising AAASchemaVersion", ex);
}
finally
{
this.DBConnection.Close();
}
}
अपडेट कोड थोड़ा अधिक जटिल है लेकिन मूल रूप से इस तरह की चीजें चलाता है:
CREATE TABLE AuditUser
(
ID int IDENTITY(1,1) NOT NULL,
UserSourceTypeID tinyint NOT NULL,
DateCreated smalldatetime NOT NULL,
UserName nvarchar(100) NOT NULL
);
ALTER TABLE AuditUser
ADD CONSTRAINT
PK_AuditUser PRIMARY KEY CLUSTERED
(
ID
),
CONSTRAINT [FK_AuditUser_UserSourceType] FOREIGN KEY
(
UserSourceTypeID
) REFERENCES UserSourceType (
ID
);
सभी एक लेन-देन प्रति अपडेट में लिपटे हुए हैं - ताकि यदि अपडेट विफल हो जाए तो आपको डेटाबेस छोड़ देना चाहिए यह एक ज्ञात अच्छी स्थिति है।
इसे इस तरह से क्यों करें (कोड में, जो इसके परीक्षणों के बिना नहीं है?) अच्छी तरह से अंतिम परिणाम आत्मविश्वास का एक उच्च स्तर है कि जिस स्कीमा से आपका ऐप बात कर रहा है वह वह स्कीमा है जिससे आपका ऐप बात करने की अपेक्षा करता है ... सही टेबल, दाएँ स्तंभ (सही क्रम में, जो सही प्रकार और सही लंबाई हैं), आदि, आदि और यह कि समय के साथ ऐसा ही होता रहेगा।
क्षमा करें अगर यह थोड़ा लंबा है - लेकिन यह कुछ ऐसा है जिसे मैं काफी उत्सुक हूं...