dotNes
dotNes

Reputation: 85

Backup a database mdf & Entity Framework

I have a database (mdf file) which I'm approaching with the Entity Framework. Is it possible to make a backup of the MDF file. I tried already but SMO but the problem is because I'm using a mdf file the database name is empty. I've read that it's autogenerated.

Piece of my backup code:

        String destinationPath = "C:\\";
        Backup sqlBackup = new Backup();

        sqlBackup.Action = BackupActionType.Database;
        sqlBackup.BackupSetDescription = "ArchiveDataBase:" + DateTime.Now.ToShortDateString();
        sqlBackup.BackupSetName = "Archive";
        
        BackupDeviceItem deviceItem = new BackupDeviceItem(destinationPath, DeviceType.File);
        ServerConnection connection = new ServerConnection(".\\SQLEXPRESS");
        Server sqlServer = new Server(connection);
        StringCollection sc = new StringCollection();
        sc.Add(Environment.CurrentDirectory + "\\db\\Xmain.mdf"); //Bin directory
        sc.Add(Environment.CurrentDirectory + "\\db\\Xmain_log.ldf");
        sqlServer.AttachDatabase("Xmain", sc);
        Database db = sqlServer.Databases["Xmain"];
        sqlBackup.Initialize = true;
        sqlBackup.Checksum = true;
        sqlBackup.ContinueAfterError = true;
        
        sqlBackup.Devices.Add(deviceItem);
        sqlBackup.Incremental = false;

        sqlBackup.ExpirationDate = DateTime.Now.AddDays(3);
        sqlBackup.LogTruncation = BackupTruncateLogType.Truncate;

        sqlBackup.FormatMedia = false;

        sqlBackup.SqlBackup(sqlServer);

Upvotes: 1

Views: 4453

Answers (2)

Afshin Razaghi
Afshin Razaghi

Reputation: 450

You must set initial catalog in connection string in app.config:

<add name="SalaryAndBenefitsEntities" connectionString="metadata=res://*/SalaryAndBenefitsModel.csdl|res://*/SalaryAndBenefitsModel.ssdl|res://*/SalaryAndBenefitsModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.\sqlexpress;attachdbfilename=|DataDirectory|SalaryAndBenefits.mdf;Initial Catalog=SalaryAndBenefit;user instance=true;password=ca;integrated security=SSPI;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />

For backUp Follow below:
create sql command content

 public string BackUpCommand(string databaseName, string fileAddress)
    {
        string command = @"BACKUP DATABASE " + databaseName + @"
                           TO DISK = '" + fileAddress + "' WITH FORMAT";
        return command;
    }

Write Backup Method:

public class ActionResult
{
    public bool Result { get; set; }
    public string Message { get; set; }
}
public ActionResult BackUpDatabase(string filePath)
    {
        ActionResult res = new ActionResult { Result = true };
        using (SalaryAndBenefitsEntities _context = new SalaryAndBenefitsEntities())
        {
            string command = "select db_name()";
            string databaseName = _context.Database.SqlQuery(typeof(string), command).ToListAsync().Result.FirstOrDefault().ToString();
            string backUpQuery = BackUpCommand(databaseName, filePath);
            var result = _context.Database.SqlQuery<List<string>>(backUpQuery).ToList();
            if (result.Count() > 0)
            {
                res.Result = false;
                result.ForEach(x =>
                {
                    res.Message += x.ToString();
                });
            }

            return res;
        }
    }

if return true database backup is successful else not

For restore Follow below:
create sql command content

public string RestoreCommand(string databaseName, string fileAddress)
    {
        string command = @"use [master]
                        ALTER DATABASE  " + databaseName + @"
                        SET SINGLE_USER
                        WITH ROLLBACK IMMEDIATE
                        RESTORE DATABASE " + databaseName + @"
                        FROM  DISK = N'" + fileAddress + "'";

        return command;
    }

Write Restore Method:

 public ActionResult RestoreDatabase(string filePath)
    {
        ActionResult res = new ActionResult { Result = true };
        using (SalaryAndBenefitsEntities _context = new SalaryAndBenefitsEntities())
        {
            string command = "select db_name()";
            string databaseName = _context.Database.SqlQuery(typeof(string), command).ToListAsync().Result.FirstOrDefault().ToString();
            string restoreQuery = RestoreCommand(databaseName, filePath);
            var result = _context.Database.SqlQuery<List<string>>(restoreQuery).ToList();
            if (result.Count() > 0)
            {
                res.Result = false;
                result.ForEach(x =>
                {
                    res.Message += x.ToString();
                });
            }
            return res;
        }
    }

if return true database restore is successful else not

the filePath Like: C:\Temp\backup.bak
the Directory of filePath (C:\Temp) must created manually before use of this methods

Upvotes: 0

Gregory A Beamer
Gregory A Beamer

Reputation: 17010

I am missing something here and need more context, but I will rant on for a second and see if anything is helpful.

Do you mean actually back up the file, not the data? If so, the easy answer is no. The problem is SQL Server will lock the file when it is attached to the database server (SQL Express in this case). You can detatch and copy and then attach, but the application will be down during that time. This can also be done manually.

If you want to backup the data, I would consider scheduling it within SQL Server rather than programmatic, unless you cannot do it that way. Backup is more of a maintenance function than a part of the program.

As for your database name being empty, that is impossible. In fact, it looks like you are trying to set up a database called XMain.

Upvotes: 1

Related Questions