2009-12-11 66 views
2

我想使用附加方法来更新通过存储过程检索的实体。使用连接与Linq到Sql和存储过程

存储过程设置为返回一个特定的实例,它存在于我的dbml中。检索按预期工作并返回一个完全填充的对象。我需要使用存储过程的原因是我需要在检索该实体的同时更新该实体的属性。

当我检索到这个实体后,我使用AutoMapper将它映射到另一个应用程序层使用的另一个模型。该层执行一些操作,并对实体进行更改,并将其传回存储库进行更新。

存储库将此业务模型转换回数据库模型,并尝试将其附加到datacontext以便利用automagic更新。

无论Attach(entity,true)Attach(entity)等是什么组合,它都会给我提供诸如“找不到或更改的行”或“无法添加具有相同主键的实体”之类的消息。

有没有人有任何关于Attach方法的经验,以及如何使用查询语法来更新不一定来自数据上下文的实体(即在这种情况下是存储过程)?

非常感谢

回答

0

1:这是相同的数据上下文,并 2:这是同一个实体实例(或一个看起来像)

这只会发生在相同的数据我怀疑这种情况。如果它是同一个实体,那么它已经在那里;只需拨打SumbitChanges即可。否则,请使用第二个数据上下文或分离原始实体。

0

因此,如果我通过存储过程检索实体,它是否被datacontext跟踪?

事情是..我要从数据模型转到另一个组件使用的另一个模型,然后返回。它不是..真的是同一个实例,但它具有所有相同的属性。

IE

public Models.Tag GetEntity() 
      { 
       var dbTag = db.PROJ_GetEntity((int)EntityStatuses.Created, (int)EntityStatuses.CreatingInApi).SingleOrDefault(); 
       return FromDb Entity(dbEntity); 
      } 


var appModel = GetEntity(); // gets an Entity from a stored proc (NOT GetEntity_RESULT) 

appModel.MakeSomeChanges(); 

_Repo.Persist(appModel); 

public void Persist(Models.AppModel model) 
{ 
var dbEntity = Mapper.Map(model); 
db.Attach(dbEntity); 
db.SubmitChanges(); 
} 

这有点伪代码一样..但它演示功能相当多,我做什么。

感谢

1

首先,如果你正在创建的对象的副本,进行更改,然后试图复制的对象连接到相同的DataContext作为一个在它原来的对象,那么这可能会导致在“无法添加具有相同主键的实体”消息中。处理此问题的一种方法是: 1.从DataContext获取对象 2.进行更改和映射对象(反之亦然 - 无论顺序如何) 3.使用在其他层中创建的新值更新原始对象 4。包含原始对象上的DataContext的SubmitChanges

  1. 获取从一个DataContext对象和关闭的DataContext
  2. 进行更改,然后做你的映射
  3. 从DataContext的检索对象,该对象您要保存
  4. 使用映射对象中的值更新该对象
  5. SubmitChanges

或者,当你说你正在使用proc,因为你需要在检索它的同时更新一个属性,我需要看到proc,但是如果你在检索后以某种方式提交了这个更新信息,那么确实消息“行未找到或改变”是正确的。这很难做到,但是如果您将数据加载到临时表中,执行更新,然后使用临时表中的选择来填充对象,则可以执行此操作。您可以尝试的一件事是在L2S设计器中将该属性设置为AutoUpdate = Never,并查看是否会导致问题消失。如果是这样,这是你的问题。

0

我正在upvoting weenet的答案,因为他是正确的 - 你不能使用附加应用更改。

与实体框架不同,只能将L2S对象附加到datacontext(如果它以前从未附加过) - 即它是您要插入到表中的新实体。

这确实会在多层环境中造成许多问题 - 但是通过创建一个使用反射和表达式树的通用实体同步系统,我能够解决许多问题。

对象被修改之后,我对DC和修改的对象中的新对象运行动态委托,以便在生成Update语句之前仅在DC中跟踪差异。不过,对相关实体有点棘手。