gpt4 book ai didi

entity-framework - Entity Framework 4 SaveChanges 不起作用并且没有抛出任何错误?

转载 作者:行者123 更新时间:2023-12-04 06:14:16 26 4
gpt4 key购买 nike

我正在尝试将我的通用存储库与“工作单元”模式一起使用。

这是我的工作详情

public  class GenericRepository:IRepository
{

private readonly string _connectionStringName;
private ObjectContext _objectContext;
private readonly PluralizationService _pluralizer = PluralizationService.CreateService(CultureInfo.GetCultureInfo("en"));

public GenericRepository()
{
this._objectContext = ContextManager.CurrentFor();
}

public void Add<TEntity>(TEntity entity) where TEntity : class
{
((DataEntities.MyTestDBEntities)_objectContext).Countries.AddObject(new Country() { CountryName="UGANDA"});
this._objectContext.AddObject(GetEntityName<TEntity>(), entity);
}

public void Update<TEntity>(TEntity entity) where TEntity : class
{
var fqen = GetEntityName<TEntity>();

object originalItem;
EntityKey key = ObjectContext.CreateEntityKey(fqen, entity);
if (ObjectContext.TryGetObjectByKey(key, out originalItem))
{
ObjectContext.ApplyCurrentValues(key.EntitySetName, entity);
}
}

private string GetEntityName<TEntity>() where TEntity : class
{
return string.Format("{0}.{1}", ObjectContext.DefaultContainerName, _pluralizer.Pluralize(typeof(TEntity).Name));
}

public object Get<TEntity>() where TEntity : class
{
var entityName = GetEntityName<TEntity>();
return ObjectContext.CreateQuery<TEntity>(entityName);
}

public IEnumerable<TEntity> Find<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class
{
return GetQuery<TEntity>().Where(criteria);
}

private IUnitOfWork unitOfWork;

public ObjectContext ObjectContext
{
get { return ContextManager.CurrentFor(); }
}

public IUnitOfWork UnitOfWork
{
get
{
if (unitOfWork == null)
{
unitOfWork = new UnitOfWork(this.ObjectContext);
}
return unitOfWork;
}
}

public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class
{
var entityName = GetEntityName<TEntity>();
return ObjectContext.CreateQuery<TEntity>(entityName);
}
}

然后我将使用 UnitOfWork.cs 重定向保存更改和其他提交事务
public class UnitOfWork:IUnitOfWork
{
private DbTransaction _transaction;
private ObjectContext _objectContext;

public UnitOfWork(ObjectContext context)
{
_objectContext = context;
}

public bool IsInTransaction
{
get { return _transaction != null; }
}

public void BeginTransaction()
{
BeginTransaction(IsolationLevel.ReadCommitted);
}

public void BeginTransaction(IsolationLevel isolationLevel)
{
if (_transaction != null)
{
throw new ApplicationException("Cannot begin a new transaction while an existing transaction is still running. " +
"Please commit or rollback the existing transaction before starting a new one.");
}
OpenConnection();
_transaction = _objectContext.Connection.BeginTransaction(isolationLevel);
}

public void RollBackTransaction()
{
if (_transaction == null)
{
throw new ApplicationException("Cannot roll back a transaction while there is no transaction running.");
}

try
{
_transaction.Rollback();
}
catch
{
throw;
}
finally
{
ReleaseCurrentTransaction();
}
}

public void CommitTransaction()
{
if (_transaction == null)
{
throw new ApplicationException("Cannot roll back a transaction while there is no transaction running.");
}

try
{
_objectContext.SaveChanges();
_transaction.Commit();
}
catch
{
_transaction.Rollback();
throw;
}
finally
{
ReleaseCurrentTransaction();
}
}

public void SaveChanges()
{
if (IsInTransaction)
{
throw new ApplicationException("A transaction is running. Call BeginTransaction instead.");
}
_objectContext.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
}

public void SaveChanges(SaveOptions saveOptions)
{
if (IsInTransaction)
{
throw new ApplicationException("A transaction is running. Call BeginTransaction instead.");
}
_objectContext.SaveChanges(saveOptions);
}

/// <summary>
/// Releases the current transaction
/// </summary>
private void ReleaseCurrentTransaction()
{
if (_transaction != null)
{
_transaction.Dispose();
_transaction = null;
}
}

private void OpenConnection()
{
if (_objectContext.Connection.State != ConnectionState.Open)
{
_objectContext.Connection.Open();
}
}

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Disposes the managed and unmanaged resources.
/// </summary>
/// <param name="disposing"></param>
private void Dispose(bool disposing)
{
if (!disposing)
return;

if (_disposed)
return;

ReleaseCurrentTransaction();

_disposed = true;
}
private bool _disposed;
}

我正在通过我的 ContextManager 获取我的上下文类(class):
public class ContextManager
{
/// <summary>
/// The default connection string name used if only one database is being communicated with.
/// </summary>
public static readonly string DefaultConnectionStringName = "DefaultDb";

/// <summary>
/// An application-specific implementation of IObjectContextStorage must be setup either thru
/// <see cref="InitStorage" /> or one of the <see cref="Init" /> overloads.
/// </summary>
private static IObjectContextStorage Storage { get; set; }

/// <summary>
/// Maintains a dictionary of object context builders, one per database. The key is a
/// connection string name used to look up the associated database, and used to decorate respective
/// repositories. If only one database is being used, this dictionary contains a single
/// factory with a key of <see cref="DefaultConnectionStringName" />.
/// </summary>
// private static Dictionary<string, IObjectContextBuilder<ObjectContext>> objectContextBuilders = new Dictionary<string, IObjectContextBuilder<ObjectContext>>();

private static object _syncLock = new object();

/// <summary>
/// Used to get the current object context session if you're communicating with a single database.
/// When communicating with multiple databases, invoke <see cref="CurrentFor()" /> instead.
/// </summary>
public static ObjectContext Current
{
get { return CurrentFor(); }
}

/// <summary>
/// Used to get the current ObjectContext associated with a key; i.e., the key
/// associated with an object context for a specific database.
///
/// If you're only communicating with one database, you should call <see cref="Current" /> instead,
/// although you're certainly welcome to call this if you have the key available.
/// </summary>
public static ObjectContext CurrentFor()
{
ObjectContext context = null;
lock (_syncLock)
{
if (context == null)
{
context =new TestDAL.DataEntities.MyTestDBEntities();
//Storage.SetObjectContextForKey(key, context);
}
}

return context;
}

/// <summary>
/// This method is used by application-specific object context storage implementations
/// and unit tests. Its job is to walk thru existing cached object context(s) and Close() each one.
/// </summary>
public static void CloseAllObjectContexts()
{
if (CurrentFor().Connection.State == System.Data.ConnectionState.Open)
{
CurrentFor().Connection.Close();
}
}
}

它让我可以检索实体,但是当我想创建一个实体时,它不会显示任何错误,也不会在数据库中显示任何更新。

任何线索都会有所帮助。

最佳答案

您的 public static ObjectContext CurrentFor()方法总是会创建一个新的上下文。您的查询正在使用 ObjectContext属性(property)

public ObjectContext ObjectContext
{
get { return ContextManager.CurrentFor(); }
}

因此,您正在使用 ObjectContext 的多个实例.您调用 SaveChanges() ObjectContext 的不同实例.因此不会保留任何更改。

不要像在 UnitOfWork 中那样显式处理事务. ObjectContext会做那部分。

你的设计是一个复杂的抽象。尝试按原样使用框架,或者找到一个已经过测试使用的简单存储库模式。

关于entity-framework - Entity Framework 4 SaveChanges 不起作用并且没有抛出任何错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7461039/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com