我尝试在Oracle 10g上的Entity Framework中使用Repository模式。我简化了我的代码:
这是SQL代码:
-- Create table
create table TESTTABLE
(
MODULE_UNIQUE_ID VARCHAR2(32) not null,
PANEL_STATUS VARCHAR2(8) not null
)
tablespace SYSTEM
pctfree 10
pctused 40
initrans 1
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
-- Create/Recreate primary, unique and foreign key constraints
alter table TESTTABLE
add constraint TESTTABLE_PK_01 unique (MODULE_UNIQUE_ID)
using index
tablespace SYSTEM
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
我创建了简单的存储库类:
public interface IRepository<TEntity, TCtx>
{
TCtx Session { get;}
void Add(TEntity entity);
void AddOrAttach(TEntity entity);
void Delete(TEntity entity);
int Save();
TEntity SelectByKey(string colName, string key);
}
public class Repository<TEntity, TCtx> : IRepository<TEntity, TCtx>,
IDisposable
where TEntity : EntityObject
where TCtx : ObjectContext
{
#region Private fields
private TCtx _ctx;
private string _keyProperty = "ID";
public int Save()
{
return _ctx.SaveChanges();
}
public TEntity SelectByKey(string colName, string key)
{
KeyProperty = colName;
// First we define the parameter that we are going to use the clause.
var xParam = Expression.Parameter(typeof(TEntity), typeof(TEntity).Name);
MemberExpression leftExpr = Expression.Property(xParam, KeyProperty);
Expression rightExpr = Expression.Constant(key);
BinaryExpression binaryExpr = Expression.Equal(leftExpr, rightExpr);
//Create Lambda Expression for the selection
Expression<Func<TEntity, bool>> lambdaExpr = Expression.Lambda<Func<TEntity, bool>>
(binaryExpr, new ParameterExpression[] { xParam });
//Searching ....
//IList<TEntity> resultCollection = ((IRepository<TEntity, TCtx>)this).SelectAll(new Specification<TEntity>(lambdaExpr));
//if (null != resultCollection && resultCollection.Count() > 0)
//{
// //return valid single result
// return resultCollection.First();
//}
//return null;
return ((IRepository<TEntity, TCtx>) this)
.SelectAll(new Specification<TEntity>(lambdaExpr)).FirstOrDefault();
}
public void Delete(TEntity entity)
{
_ctx.DeleteObject(entity);
}
}
问题首先我选择了一些实体然后我想要删除。 选择适用于Oracle DB的工作。问题是更新或删除命令。
var _repo = new Repository<TESTTABLE, Entities>(
new Entities(ConfigurationManager.ConnectionStrings["Entities"]
.ConnectionString));
var obj = _repo.SelectByKey("MODULE_UNIQUE_ID", "11111");
_repo.Delete(obj);
_repo.Save();
我得到了这个例外:
{“更新条目时发生错误。请参阅内部 细节例外。“}
内部异常:
{“由于对象的当前状态,操作无效。”}
堆栈跟踪:
在 System.Data.Mapping.Update.Internal.UpdateTranslator.CreateCommand(DbModificationCommandTree commandTree)at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.CreateCommand(UpdateTranslator 译者,词典
2 identifierValues) at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary
2 identifierValues,List`1 generatedValues)at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager,IEntityAdapter适配器)
我再次测试了我的存储库类MS SQL数据库它运行良好。
什么可能导致这个问题?
答案 0 :(得分:1)
我记得看到过这样的事情:
_context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
保存
MSDN Notes http://msdn.microsoft.com/en-us/library/system.data.objects.objectstatemanager.aspx
相关帖子ObjectContext tracking changes in Entity Framwwork
出于性能原因,您可以加载没有更改跟踪的对象
答案 1 :(得分:0)
看起来您在不使用ObjectContext的情况下检索对象。
因此,加载的对象不会附加到上下文。
当您尝试通过上下文删除它时,实体的当前状态为“已分离”,这对于删除操作无效。