我剛剛開始學習和使用ADO.NET實體框架並遇到了一些問題。有時,我的Wifi連接到路由器時發生故障,因此無法連接到網絡中另一臺計算機上的數據庫。失敗的連接導致我的整個應用程序凍結約20秒,然後拋出異常。我想捕捉異常並顯示自定義錯誤消息,但是我不想在每個查詢周圍使用try-catch。.NET實體框架連接失敗
這是我試圖做的。我創建了一個靜態方法來創建一個上下文,每當我需要一個時,並將其包裝在try-catch語句中,以嘗試捕獲連接錯誤,並且在有連接之前不會繼續,或者用戶向MessaeBox回答No並退出應用。
public static MySqlEntities Database
{
get
{
try
{
// create a new context
MySqlEntities db = new MySqlEntities();
// return it upon success
return db;
}
catch (Exception ex)
{
// show error message upon failute
MessageBoxResult result = MessageBox.Show("Failed to establish a connection with the database. Please verify that the database server is online, would you like to try again?", "Database Connection Failure", MessageBoxButton.YesNo);
// close the application if they don't wanna try again
if (result == MessageBoxResult.No)
{
Fx.Window.Close();
return null;
}
// otherwise try again
return Fx.Database;
}
}
}
這裏是我寫的選擇,更新和添加數據到/從數據庫中的庫類。
public class EmployeeRepository
{
#region SelectQuery
/// <summary>
/// Compiled query for selecting a range of Employees.
/// </summary>
protected static readonly Func<MySqlEntities, int, int, IQueryable<Employee>> SelectQuery =
CompiledQuery.Compile<MySqlEntities, int, int, IQueryable<Employee>>(
(db, start, limit) =>
(from t in db.Employees orderby t.ID select t).Skip(start).Take(limit)
);
#endregion
#region SelectyByIDQuery
/// <summary>
/// Compiled query for selecting a single Employee by ID.
/// </summary>
protected static readonly Func<MySqlEntities, int, Employee> SelectByIDQuery =
CompiledQuery.Compile<MySqlEntities, int, Employee>(
(db, id) =>
(from t in db.Employees where t.ID == id select t).FirstOrDefault()
);
#endregion
#region SelectByUsernameQuery
/// <summary>
/// Compiled query for selecting a single Employee by Username.
/// </summary>
protected static readonly Func<MySqlEntities, string, Employee> SelectByUsernameQuery =
CompiledQuery.Compile<MySqlEntities, string, Employee>(
(db, username) =>
(from t in db.Employees where t.Username == username select t).FirstOrDefault()
);
#endregion
#region SearchQuery
/// <summary>
/// Compiled query for searching Employees by Name and Username
/// </summary>
protected static readonly Func<MySqlEntities, string, int, IQueryable<Employee>> SearchQuery =
CompiledQuery.Compile<MySqlEntities, string, int, IQueryable<Employee>>(
(db, search, limit) =>
(from t in db.Employees where t.Name.StartsWith(search) || t.Username.StartsWith(search) select t).Take(limit)
);
#endregion
/// <summary>
/// Select a range of Employees start at a specific offset.
/// </summary>
/// <param name="start">The starting position.</param>
/// <param name="limit">The maximum number of employees to select.</param>
/// <returns></returns>
public static List<Employee> Select(int start = 0, int limit = 10)
{
using (var db = Fx.Database)
return new List<Employee>(SelectQuery.Invoke(db, start, limit));
}
/// <summary>
/// Select a single Employee with a matching ID.
/// </summary>
/// <param name="id">The ID to search for.</param>
/// <returns></returns>
public static Employee SelectByID(int id)
{
using (var db = Fx.Database)
return SelectByIDQuery.Invoke(db, id);
}
/// <summary>
/// Select a single Employee with a matching Username.
/// </summary>
/// <param name="username">The Username to search for.</param>
/// <returns></returns>
public static Employee SelectByUsername(string username)
{
using (var db = Fx.Database)
return SelectByUsernameQuery.Invoke(db, username);
}
/// <summary>
/// Search for Employees by Name and Username.
/// </summary>
/// <param name="search">The search string.</param>
/// <param name="limit">The maximum number of Employees to select.</param>
/// <returns></returns>
public static List<Employee> Search(string search, int limit = 10)
{
using (var db = Fx.Database)
return new List<Employee>(SearchQuery.Invoke(db, search, limit));
}
/// <summary>
/// Save changes to an Employee to the database.
/// </summary>
/// <param name="employee">The Employee object to save.</param>
public static bool Save(Employee employee)
{
using(var db = Fx.Database)
{
db.Employees.Attach(employee);
db.Employees.Context.ObjectStateManager.ChangeObjectState(employee, System.Data.EntityState.Modified);
try
{
db.SaveChanges();
return true;
}
catch (Exception ex)
{
MessageBox.Show("Failed to save employee:\n\n" + ex.InnerException.Message);
return false;
}
}
}
/// <summary>
/// Add an Employee to the database.
/// </summary>
/// <param name="employee">The Employee object to add.</param>
public static bool Add(Employee employee)
{
using (var db = Fx.Database)
{
db.Employees.AddObject(employee);
try
{
db.SaveChanges();
return true;
}
catch (Exception ex)
{
MessageBox.Show("Failed to add employee:\n\n" + ex.InnerException.Message);
return false;
}
}
}
}
這裏是我如何使用EmployeeRepository類的例子...
Employee Employee = EmployeeRepository.SelectByUsername(UsernameInput.Text);
if(Employee == null || Employee.Password != PasswordInput.Password)
MessageBox.Show("Invalid login credentials.");
else
MessageBox.Show("Logged in successfully.");
的問題是,這不起作用,因爲正在執行查詢時異常被拋出之後和不是當我創建上下文時。
所以我的問題....
我怎樣才能趕上連接錯誤,創建並顯示我的自定義錯誤消息的上下文時。
請將此分成兩個問題,然後在superuser.com或serverfault.com上發佈您的第三個問題。 –
他的問題與超級用戶或serverfault有什麼關係? – Jeff
@ JeffN825在那之前我還有一個問題涉及更多的網絡問題。 –