无法更新EntitySet-因为它具有DefiningQuery并且没有 <UpdateFunction> 元素存在

本文翻译自:Unable to update the EntitySet - because it has a DefiningQuery and no element exist

I am using Entity Framework 1 with .net 3.5. 我正在将Entity Framework 1与.net 3.5配合使用。

I am doing something simple like this: 我正在做这样简单的事情:

var RoomDetails = context.Rooms.ToList();

foreach (var Room in Rooms)
{        
   Room.LastUpdated = DateTime.Now;
}

I am getting this error when I try to do: 我尝试执行此操作时遇到此错误:

 context.SaveChanges();

I get the error: 我收到错误:

Unable to update the EntitySet - because it has a DefiningQuery and no <UpdateFunction> element exists in the <ModificationFunctionMapping> element to support the current operation. 无法更新EntitySet-因为它具有DefiningQuery,并且<ModificationFunctionMapping>元素中不存在任何<UpdateFunction>元素来支持当前操作。

I am doing lots of updates on the context and not having any issues, it's only when I try to update this particular entity. 我正在上下文中进行大量更新,并且没有任何问题,仅当我尝试更新此特定实体时。

All my searching shows up the same thing, that there is no primary key declared on the entity that I'm trying to update. 我所有的搜索都显示相同的内容,即我要更新的实体上没有声明主键。 But alas, I do have a Primary key declared... 但是a,我确实声明了主键...


#1楼

参考:https://stackoom.com/question/Voss/无法更新EntitySet-因为它具有DefiningQuery并且没有-UpdateFunction-元素存在


#2楼

This can also happen if data model is out of date. 如果数据模型过时,也会发生这种情况。

Hopefully this will save someone else frustration :) 希望这可以避免其他人的沮丧:)


#3楼

Just Add a primary key to the table. 只需在表中添加一个主键即可。 That's it. 而已。 Problem solved. 问题解决了。

ALTER TABLE <TABLE_NAME>
ADD CONSTRAINT <CONSTRAINT_NAME> PRIMARY KEY(<COLUMN_NAME>)

#4楼

请注意,也许您的实体具有主键,但是数据库的表却没有主键


#5楼

I was getting the same error message, but in my scenario I was trying to update entities derived from a many-to-many relationship using a PJT (Pure Join Table). 我收到了同样的错误消息,但是在我的场景中,我试图使用PJT(纯联接表)更新从多对多关系派生的实体。

From reading the other posts, I thought I could fix it by adding an additional PK field to the join table... However, if you add a PK column to a join table, it is no longer a PJT and you lose all of the entity framework advantages like the automatic relationship mapping between the entities. 通过阅读其他文章,我想我可以通过在联接表中添加一个额外的PK字段来解决此问题。但是,如果在联接表中添加PK列,则它不再是PJT,并且您将失去所有实体框架的优势,例如实体之间的自动关系映射。

So the solution in my case was to alter the join table on the DB to make a PK that includes BOTH of the foreign ID columns. 因此,在我的情况下,解决方案是更改数据库上的联接表,以创建一个包含两个外部ID列的PK。


#6楼

UPDATE: I've gotten a few upvotes on this lately, so I figured I'd let people know the advice I give below isn't the best. 更新:我最近对此有一些反对意见,所以我想让人们知道我在下面给出的建议不是最好的。 Since I originally started mucking about with doing Entity Framework on old keyless databases, I've come to realize that the best thing you can do BY FAR is do it by reverse code-first. 自从我最初开始考虑在旧的无密钥数据库上执行Entity Framework以来,我逐渐认识到BY FAR可以做的最好的事情就是先进行反向代码。 There are a few good articles out there on how to do this. 关于如何执行此操作的文章不错。 Just follow them, and then when you want to add a key to it, use data annotations to "fake" the key. 只需跟随它们,然后在要向其添加密钥时,使用数据注释“伪造”密钥。

For instance, let's say I know my table Orders , while it doesn't have a primary key, is assured to only ever have one order number per customer. 例如,假设我知道我的表Orders ,虽然它没有主键,但可以确保每个客户只有一个订单号。 Since those are the first two columns on the table, I'd set up the code first classes to look like this: 由于这些是表的前两列,因此我将代码优先类设置为如下所示:

    [Key, Column(Order = 0)]
    public Int32? OrderNumber { get; set; }

    [Key, Column(Order = 1)]
    public String Customer { get; set; }

By doing this, you're basically faked EF into believing that there's a clustered key composed of OrderNumber and Customer. 通过这样做,您基本上是在使EF假装EF认为存在由OrderNumber和Customer组成的集群密钥。 This will allow you to do inserts, updates, etc on your keyless table. 这将允许您在无密钥表上进行插入,更新等操作。

If you're not too familiar with doing reverse Code First, go and find a good tutorial on Entity Framework Code First. 如果您不太熟悉执行反向代码优先,请去查找有关Entity Framework Code First的很好的教程。 Then go find one on Reverse Code First (which is doing Code First with an existing database). 然后在Reverse Code First上找到一个(正在使用现有数据库执行Code First)。 Then just come back here and look at my key advice again. 然后回到这里,再次查看我的主要建议。 :) :)

Original Answer : 原始答案

First: as others have said, the best option is to add a primary key to the table. 第一:正如其他人所说,最好的选择是向表添加主键。 Full stop. 句号 If you can do this, read no further. 如果可以这样做,请继续阅读。

But if you can't, or just hate yourself, there's a way to do it without the primary key. 但是,如果您不能或者只是讨厌自己,那么有一种方法可以在没有主键的情况下进行。

In my case, I was working with a legacy system (originally flat files on a AS400 ported to Access and then ported to T-SQL). 就我而言,我使用的是旧版系统(最初是将AS400上的平面文件移植到Access,然后移植到T-SQL)。 So I had to find a way. 所以我必须找到一种方法。 This is my solution. 这是我的解决方案。 The following worked for me using Entity Framework 6.0 (the latest on NuGet as of this writing). 以下内容使用Entity Framework 6.0(在撰写本文时,它是NuGet的最新版本)对我有用。

  1. Right-click on your .edmx file in the Solution Explorer. 在解决方案资源管理器中右键单击您的.edmx文件。 Choose "Open With..." and then select "XML (Text) Editor". 选择“打开方式...”,然后选择“ XML(文本)编辑器”。 We're going to be hand-editing the auto-generated code here. 我们将在这里手动编辑自动生成的代码。

  2. Look for a line like this: 寻找这样的一行:
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" store:Schema="dbo" store:Name="table_nane">

  3. Remove store:Name="table_name" from the end. 从最后删除store:Name="table_name"

  4. Change store:Schema="whatever" to Schema="whatever" store:Schema="whatever"更改为Schema="whatever"

  5. Look below that line and find the <DefiningQuery> tag. 在该行下面查找并找到<DefiningQuery>标记。 It will have a big ol' select statement in it. 它将有一个很大的选择语句。 Remove the tag and it's contents. 删除标签及其内容。

  6. Now your line should look something like this: 现在您的行应如下所示:
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />

  7. We have something else to change. 我们还有其他改变。 Go through your file and find this: 浏览您的文件并找到以下内容:
    <EntityType Name="table_name">

  8. Nearby you'll probably see some commented text warning you that it didn't have a primary key identified, so the key has been inferred and the definition is a read-only table/view. 在附近,您可能会看到一些注释文本,警告您未标识主键,因此已推断出该键,并且该定义是只读表/视图。 You can leave it or delete it. 您可以保留或删除它。 I deleted it. 我删除了它。

  9. Below is the <Key> tag. 下面是<Key>标记。 This is what Entity Framework is going to use to do insert/update/deletes. 这就是Entity Framework将用于执行插入/更新/删除的操作。 SO MAKE SURE YOU DO THIS RIGHT. 因此,请确保您这样做是正确的。 The property (or properties) in that tag need to indicate a uniquely identifiable row. 该标记中的一个或多个属性需要指示一个唯一可识别的行。 For instance, let's say I know my table orders , while it doesn't have a primary key, is assured to only ever have one order number per customer. 例如,假设我知道我的餐桌orders ,虽然它没有主键,但可以确保每个客户只有一个订单号。

So mine looks like: 所以我的看起来像:

<EntityType Name="table_name">
              <Key>
                <PropertyRef Name="order_numbers" />
                <PropertyRef Name="customer_name" />
              </Key>

Seriously, don't do this wrong. 认真地说,不要做错这个。 Let's say that even though there should never be duplicates, somehow two rows get into my system with the same order number and customer name. 假设即使永远都不会重复,但还是会有两行以相同的订单号和客户名进入我的系统。 Whooops! 哎呀! That's what I get for not using a key! 那就是我不使用钥匙而得到的! So I use Entity Framework to delete one. 所以我使用实体框架删除一个。 Because I know the duplicate is the only order put in today, I do this: 因为我知道重复项是今天发出的唯一订单,所以我这样做:

var duplicateOrder = myModel.orders.First(x => x.order_date == DateTime.Today);
myModel.orders.Remove(duplicateOrder);

Guess what? 你猜怎么了? I just deleted both the duplicate AND the original! 我只是删除了重复的和原始的! That's because I told Entity Framework that order_number/cutomer_name was my primary key. 那是因为我告诉实体框架,order_number / cutomer_name是我的主键。 So when I told it to remove duplicateOrder, what it did in the background was something like: 因此,当我告诉它删除重复订单时,它在后台执行的操作类似于:

DELETE FROM orders
WHERE order_number = (duplicateOrder's order number)
AND customer_name = (duplicateOrder's customer name)

And with that warning... you should now be good to go! 有了那个警告...您现在应该可以了!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值