csharp 实体框架数据库异常类
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp 实体框架数据库异常类相关的知识,希望对你有一定的参考价值。
using System;
using System.Data;
// TODO change namespace
namespace Nycb.Kyc.Data
{
/// <summary>
/// Transaction Isolation Level.
/// </summary>
public class TransactionIsolationLevel : IDisposable
{
/// <summary>
/// The database connection.
/// </summary>
private readonly IDbConnection _connection;
/// <summary>
/// Original isolation level of the connection.
/// </summary>
private readonly IsolationLevel _originalIsolationLevel;
/// <summary>
/// Initializes a new instance of the TransactionIsolationLevel class.
/// </summary>
/// <param name="connection">Database connection as <see cref="IDbConnection"/></param>
/// <param name="isolationLevel">Required isolation level as <see cref="IsolationLevel"/></param>
public TransactionIsolationLevel(IDbConnection connection, IsolationLevel isolationLevel)
{
_connection = connection;
_originalIsolationLevel = _connection.GetIsolationLevel();
_connection.SetIsolationLevel(isolationLevel);
}
/// <summary>
/// Resets the isolation level back to the original value.
/// </summary>
public void Dispose()
{
_connection.SetIsolationLevel(_originalIsolationLevel);
}
}
}
using System;
using System.Data.Entity.Validation;
using System.Text;
// TODO change namespace
namespace EntityValidationExtension
{
public class FormattedDbEntityValidationException : Exception
{
public FormattedDbEntityValidationException(DbEntityValidationException validationException) :
base(null, validationException)
{
}
public override string Message
{
get
{
var innerException = InnerException as DbEntityValidationException;
if (innerException != null)
{
var sb = new StringBuilder();
sb.AppendLine();
sb.AppendLine();
foreach (var eve in innerException.EntityValidationErrors)
{
sb.AppendLine(string.Format("- Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().FullName, eve.Entry.State));
foreach (var ve in eve.ValidationErrors)
{
sb.AppendLine(string.Format("-- Property: \"{0}\", Value: \"{1}\", Error: \"{2}\"",
ve.PropertyName,
eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName),
ve.ErrorMessage));
}
}
sb.AppendLine();
return sb.ToString();
}
return base.Message;
}
}
}
}
using System.Data.Entity;
using System.Data.Entity.Validation;
// TODO change namespace
namespace EntityValidationExtension
{
public DbContextExtended()
{ }
public DbContextExtended(string dbName) : base(dbName)
{ }
public class DbContextExtended : DbContext
{
public override int SaveChanges()
{
try
{
var isoLevel = IsolationLevel.Serializable;
if (Database.Connection.IsSnapshotIsolotionEnabled())
isoLevel = IsolationLevel.Snapshot;
// Set isolation level run transaction and reset back to original DB setting
using (var inner = new TransactionIsolationLevel(Database.Connection, isoLevel))
{
return base.SaveChanges();
}
}
catch (DbEntityValidationException e)
{
var newException = new FormattedDbEntityValidationException(e);
throw newException;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Core.EntityClient;
using System.Data.SqlClient;
// TODO change namespace
namespace Nycb.Kyc.Data
{
/// <summary>
/// Extension methods for database connection.
/// </summary>
public static class ConnectionExtensions
{
/// <summary>
/// Translates an isolation level to its T-SQL name.
/// </summary>
private static readonly Dictionary<IsolationLevel, string> IsolationLevels = new Dictionary<IsolationLevel, string>();
// cache value for efficency
private static bool? _snapshotIsolationEnabled;
static ConnectionExtensions()
{
IsolationLevels[IsolationLevel.ReadUncommitted] = "READ UNCOMMITTED";
IsolationLevels[IsolationLevel.ReadCommitted] = "READ COMMITTED";
IsolationLevels[IsolationLevel.RepeatableRead] = "REPEATABLE READ";
IsolationLevels[IsolationLevel.Snapshot] = "SNAPSHOT";
IsolationLevels[IsolationLevel.Serializable] = "SERIALIZABLE";
}
/// <summary>
/// Check if the DB has Snapshot Isolation Enabled
/// </summary>
/// <param name="conn">The connection as <see cref="IDbConnection"/></param>
/// <returns>Enabled as <see cref="bool"/></returns>
public static bool IsSnapshotIsolotionEnabled(this IDbConnection conn)
{
if (_snapshotIsolationEnabled.HasValue)
return _snapshotIsolationEnabled.Value;
var db = conn.Database;
var query = @"SELECT is_read_committed_snapshot_on FROM sys.databases WHERE name= '" + db + "'";
var entityConnection = conn as EntityConnection;
if (entityConnection != null)
{
var command = entityConnection.StoreConnection.CreateCommand();
command.CommandText = query;
if (conn.State != ConnectionState.Open && conn.State != ConnectionState.Connecting)
conn.Open();
_snapshotIsolationEnabled = (bool)command.ExecuteScalar();
return _snapshotIsolationEnabled.Value;
}
if (conn is SqlConnection)
{
var command = conn.CreateCommand();
command.CommandText = query;
if (conn.State != ConnectionState.Open && conn.State != ConnectionState.Connecting)
conn.Open();
_snapshotIsolationEnabled = (bool)command.ExecuteScalar();
return _snapshotIsolationEnabled.Value;
}
return false;
}
/// <summary>
/// Gets the current transaction isolation level on a connection.
/// </summary>
/// <param name="conn">The connection as <see cref="IDbConnection"/></param
/// <returns>The transaction isolation level as <see cref="IsolationLevel"/></returns>
public static IsolationLevel GetIsolationLevel(this IDbConnection conn)
{
const string query = @"SELECT CASE transaction_isolation_level
WHEN 0 THEN 'Unspecified'
WHEN 1 THEN 'ReadUncommitted'
WHEN 2 THEN 'ReadCommitted'
WHEN 3 THEN 'RepeatableRead'
WHEN 4 THEN 'Serializable'
WHEN 5 THEN 'Snapshot'
END AS [Transaction Isolation Level]
FROM sys.dm_exec_sessions
WHERE session_id = @@SPID";
var entityConnection = conn as EntityConnection;
if (entityConnection != null)
{
return entityConnection.StoreConnection.GetIsolationLevel();
}
if (conn is SqlConnection)
{
var command = conn.CreateCommand();
command.CommandText = query;
if (conn.State != ConnectionState.Open && conn.State != ConnectionState.Connecting)
conn.Open();
var result = command.ExecuteScalar().ToString();
return (IsolationLevel)Enum.Parse(typeof(IsolationLevel), result);
}
return IsolationLevel.Unspecified;
}
/// <summary>
/// Sets the transaction level on a connection.
/// </summary>
/// <param name="conn">The connection as <see cref="IDbConnection"/></param
/// <param name="isolationLevel">The new isolation level as <see cref="IsolationLevel"/></param>
public static void SetIsolationLevel(this IDbConnection conn, IsolationLevel isolationLevel)
{
if (isolationLevel == IsolationLevel.Unspecified || isolationLevel == IsolationLevel.Chaos)
{
throw new Exception($"Isolation Level '{isolationLevel}' can not be set.");
}
var entityConnection = conn as EntityConnection;
if (entityConnection != null)
{
var sqlConnection = entityConnection.StoreConnection as SqlConnection;
sqlConnection.SetIsolationLevel(isolationLevel);
}
else if (conn is SqlConnection)
{
var command = conn.CreateCommand();
command.CommandText = $"SET TRANSACTION ISOLATION LEVEL {IsolationLevels[isolationLevel]}";
command.ExecuteNonQuery();
}
}
}
}
以上是关于csharp 实体框架数据库异常类的主要内容,如果未能解决你的问题,请参考以下文章
实体类和数据表的映射异常(XXX is not mapping[ ])
csharp 使用外键使用实体框架和数据库第一模型进行级联删除的示例。