EF 4.1 - 如果不存在则插入实体,否则使用现有实体 - 如何?

时间:2011-10-30 02:33:21

标签: c# entity-framework-4.1

这是一个场景: 有用户,用户有技能。如果用户指定了新技能,则需要添加该技能,但是如果用户指定现有技能,则应该链接到现有技能。 因此,设置非常基本 - 3个表(用户,技能,userSkillsLink)。这是一个网络应用程序,但我不想在下拉列表中添加所有技能 - 所以我不知道技能是否立即存在。我可以使用select来检查技能是否已经存在,但是在不是最佳选择的Web应用程序中 - 不是线程安全的。 我可以跟踪已经存在于单独缓存中的哪些技能,但这个问题应该是......非常常见,所以我想也许我过于复杂了,而且已经有一个已知的解决方案。

谢谢!

2 个答案:

答案 0 :(得分:2)

我将创建一个存储过程,该过程将技能名称作为参数,执行检查并根据需要插入新记录,然后返回结果记录(现有记录或新记录)。

然后我可以将该过程映射到DbContext上的方法,并使该方法返回一个实体。

然后我可以称之为:var skill = database.GetSkillCreateIfNone( skillName )

答案 1 :(得分:1)

我认为用事务语义解决这个问题的正确方法是:

  • 使潜在共享值成为其表的主键,以确保它是唯一的
  • 查询以填充下拉列表并将结果存储在本地缓存中
  • 如果记录存在于缓存中,请重复使用
  • 如果记录不存在,请创建

然后通过让事务抛出异常来处理并发。在异常处理程序中,您可以重新查询并使用现有值。

如果您的交易再次死亡(如果记录被删除),只需向用户提供相应的错误消息,并告诉他们再试一次。

你不能以任何其他方式真正做到这一点,因为除了将它包装在事务中之外,你甚至不能在存储过程中进行原子查询和提交。