Entity Framework : "저장소 업데이트, 삽입 또는 삭제 문이 예기치 않은 행 수 (0)에 영향을 미쳤습니다." [닫은]


324

Entity Framework를 사용하여 그리드 컨트롤을 채우고 있습니다. 때때로 업데이트 할 때 다음 오류가 발생합니다.

저장소 업데이트, 삽입 또는 삭제 문이 예기치 않은 행 수 (0)에 영향을 미쳤습니다. 엔터티가로드 된 후 엔터티가 수정되거나 삭제되었을 수 있습니다. ObjectStateManager 항목을 새로 고칩니다.

이것을 재현하는 방법을 알 수 없습니다. 그러나 업데이트를 얼마나 가깝게 수행하는지와 관련이 있습니다. 누구든지 이것을 보았거나 오류 메시지가 무엇을 의미하는지 아는 사람이 있습니까?

편집 : 불행히도 나는이 프로젝트에서 물러 났고 궁극적으로 솔루션을 찾았는지, 다른 개발자가 해결했는지, 또는 해결했는지 여부를 기억하지 못하기 때문에 더 이상 자유의 여지가 없습니다. 그러므로 나는 어떤 대답도 받아 들일 수 없습니다.


행을 갱신 할 수없는 상태 (허용 BLOCK 술어가있는 독점 FILTER 술어)로 갱신 할 수 있는 SQL Server 행 레벨 보안 정책이 도입되면서이 오류가 발생했습니다 . EntityFramework는 업데이트 후 업데이트 된 행을 다시 읽도록 요구합니다. 그렇지 않으면 동시성 오류라고 가정합니다 (적어도 낙관적 동시성을 사용하는 경우).
xr280xr

문제는 DBContext stackoverflow.com/questions/49154250/…에 대해 잘못된 범위 지정이 될 수 있습니다 (이 예제는 ASPNET Identity 용이지만 모든 컨텍스트에 적용됨)
Simon_Weaver

이 오류의 컨텍스트에 관계없이 컨텍스트가 인스턴스화되는 위치에 중단 점을 두는 것이 좋습니다. 웹 페이지를로드 할 때 한 번 인스턴스화 될 것으로 예상했지만 중단 점을 5 번 누르는가? 그렇다면 경쟁 조건이있을 수 있습니다. 봐 Request.Uri실제 요청 URL을 볼 수 있습니다. 내 경우에는 내 사이트를 공격하고 불필요하게 DB에서 컨텍스트를로드하고 때로는 업데이트하는 추적 논리가있었습니다. 그래서 내가 디버깅하고 있던 실제 페이지는 바보 추적 코드 로직에 의해 데이터가 스톰되었습니다.
Simon_Weaver

뷰에 @ Html.AntiForgeryToken () 추가
Vikas Sharma

답변:


199

그것은 낙관적 동시성이라는 기능의 부작용입니다.

Entity Framework에서 켜거나 끄는 방법을 100 % 확신하지 못하지만 기본적으로 데이터베이스에서 데이터를 가져 오는 시점과 변경 사항을 저장 한 시점 사이에 다른 사람이 데이터를 변경 한 시점 사이에 저장하려면 0 행이 실제로 업데이트되었습니다). SQL 용어로 update쿼리where 절에는 행에있는 모든 필드의 원래 값이 포함되며 0 개의 행이 영향을받는 경우 무언가 잘못되었음을 알 수 있습니다.

그 뒤에 아이디어는 응용 프로그램이 알지 못했던 변경 사항을 덮어 쓰지 않을 것이라는 것입니다. 기본적으로 모든 업데이트에서 .NET에 의해 발생하는 약간의 안전 조치입니다.

일관성이 있다면 자신의 논리 (EG : 실제로 선택과 업데이트 사이의 다른 방법으로 데이터를 직접 업데이트하고 있음) 내에서 발생할 가능성이 있지만 두 응용 프로그램 간의 경쟁 조건 일 수 있습니다.


34
이것은 내 사용자 컴퓨터의 단일 사용자 환경에서 발생하므로 경쟁 조건 일 수 있다고 생각하지 않습니다. EntityDataSource를 사용하여 사용자 지정 그리드 컨트롤에 바인딩하므로 장면 뒤에서 정확히 무슨 일이 일어나고 있는지 확실하지 않지만 테이블을 수정하는 추가 코드가 없습니다. 이 동시성 설정을 변경하는 방법이 있습니까?
strongopinions 2018

3
엔터티 모델에서 열별로 할 수 있다고 생각하지만 (속성 창에 있음) 오류가 발생하는 것을 막을 수 있으며 여전히 아무것도 업데이트하지 않습니다. 데이터베이스로 이동하는 SQL 명령 (예 : MSSQL 용 SQL Server 프로파일 러)을 볼 수 있습니까? 이렇게하면 어떤 업데이트가 생성되는지 확인할 수 있으며 해당 업데이트가 행에 영향을 미치지 않는 이유를 확인할 수 있습니다.
fyjham 2009

9
엔터티에 타임 스탬프 속성이 있으면 뷰에 저장하고 엔터티가 타임 스탬프를 올바르게 채우도록하십시오.
IBMer

나는 타임 스탬프 열을했고 나는 그것을 해결하면, EF6.1는 예상대로 팁 @anelBMer에 대한 감사 일
JQII

3
타임 스탬프를 사용하는 경우 삭제하려는 객체에 PK 세트와 RowVersion 속성이 필요합니다. 객체를 각 DbSet에 첨부 한 후 rowVersion (timestamp) 속성을 설정하고 있었기 때문에 작동하지 않습니다. 잘 했어!
Legends

394

이 문제가 발생하여 엔티티의 ID (키) 필드가 설정되지 않아 발생했습니다. 따라서 컨텍스트가 데이터를 저장하려고 할 때 ID = 0을 찾을 수 없습니다. 업데이트 명령문에 중단 점을 배치하고 엔티티의 ID가 설정되었는지 확인하십시오.

Paul Bellora의 의견에서

.cshtml 편집 페이지에 숨겨진 ID 입력을 포함시키는 것을 잊어 버리기 때문에이 정확한 문제가 발생했습니다.


3
+1 같은 문제가 발생하여 해결책을 찾는 데 도움이되었습니다. 내 주문 모델에 [Bind (Exclude = "OrderID")]가있어서 HttpPost에서 엔티티 ID 값이 0이 되었음이 밝혀졌습니다.
배기

2
그것이 바로 내가 놓친 것입니다. 내 개체의 ID는 0입니다.
Azhar Khorasany

4
@ Html.HiddenFor (model => model.productID)-완벽하게 작동했습니다. 내가 편집 페이지 (MVC RAZOR)에서 제품 ID 실종됐다
라비 램

2
비슷한 문제가 있었지만 비틀어졌습니다. 나에게 문제는 SQL 테이블 설정이 올바르게 없다는 것입니다. 기본 키 필드가 자동 증분으로 설정되지 않았습니다. 따라서 EF는 내가 w / oa 키를 삽입하려고 시도한 레코드를 보낼 것입니다. sql에 필드가 자동 증분 ID 필드라는 것을 기억하는 경우 괜찮습니다. <
Agile Noob

1
같은 문제이지만 복합 키를 사용합니다. 키 값 중 하나가 설정되지 않았습니다.
obaylis

113

와우, 많은 답변이지만 다른 언급이없는 약간 다른 것을했을 때이 오류가 발생했습니다.

간단히 말해서, 새 객체를 만들고 EF에 객체를 사용하여 수정했다고 알려 EntityState.Modified주면 데이터베이스에 아직 존재하지 않으므로이 오류가 발생합니다. 내 코드는 다음과 같습니다.

MyObject foo = new MyObject()
{
    someAttribute = someValue
};

context.Entry(foo).State = EntityState.Modified;
context.SaveChanges();

그렇습니다. 이것은 어리석은 것처럼 보이지만 foo이전에 전달 된 방법이 이전에 생성 되었기 때문에 발생 someValue했습니다 foo.

쉽게 고쳐, 단지 변화 EntityState.ModifiedEntityState.Added또는 변경이 전체 라인 :

context.MyObject.Add(foo);

이것을 게시 해 주셔서 감사합니다. 그것도 내 문제 였고 State를 EntityState.Modified로 설정하는 일부 코드를 복사하여 붙여 넣었습니다.
clayRay

23

나는이 같은 끔찍한 오류에 직면했다 ... :) 그런 다음 나는 설정하는 것을 잊고 있다는 것을 깨달았다.

@Html.HiddenFor(model => model.UserProfile.UserId)

업데이트되는 객체의 기본 키! 나는이 단순하지만 매우 중요한 것을 잊는 경향이있다!

그건 그렇고 : HiddenForASP.NET MVC입니다.


3
즉를 저장, 보안 결함처럼 보인다 UserId해커 매우 쉬운 형태로 ...이에서 나중에 채워 져야합니다HttpContext.Current.User.Identity.Name
Serj 세이건

@SerjSagan 당신 말이 맞습니다 ...하지만 서버 측에서 UserId 및 현재 UserName을 확인하기 위해 몇 가지 검사를 수행하면 좋습니다.
Leniel Maccaferri

1
내 요점은 어쨌든 HiddenFor그것을 HttpContext가져와야 할 때까지 저장 해야하는 이유입니다 ... 나는이 속성을 전혀 양식에 넣지 않을 것이므로 항상 서버 측에 채워야합니다 ...
Serj Sagan

16

GridView에서 "DataKeyNames"속성을 잊었는지 확인하십시오. GridView 내에서 데이터를 수정할 때 필수입니다.

http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx


+1. 나를위한 완벽하고 간단한 솔루션. GridView를 EntityDataSource에 바인딩하고 있으며 객체의 기본 키로 설정하지 않았습니다.
Andez

우리는 Kendo UI가 복합 키를 지원하지 않는다는 것을 알고 있지만 키를 하나로 연결하는 새 열을 추가 한 경우 어떻게됩니까?
브라 니 슬라 프

15

이 문제는 다음 두 가지 중 하나에 의해 발생합니다.

  1. 하나 이상의 속성이 Concurrency Mode: Fixed.. 인 행을 업데이트하려고 시도 했으며 낙관적 동시성으로 인해 데이터가 저장되지 않았습니다. 즉. 일부는 서버 데이터를 수신 한 시간과 서버 데이터를 저장 한 시간 사이에 행 데이터를 변경했습니다.
  2. 행을 업데이트하거나 삭제하려고했지만 해당 행이 없습니다. 검색 후 저장 사이에 데이터를 변경 (이 경우 제거)하는 다른 예는 저장하지 않거나 Identity (예 :)가 아닌 필드를 업데이트하려고하면 StoreGeneratedPattern = Computed행이 존재하지 않습니다.

1
할당 된 모든 객체 속성이 이전과 동일한 값으로 할당 된 경우에도 발생할 수 있습니다.
Serj Sagan

2 번째 +1 StoreGeneratedPattern = None이 있는데 StoreGeneratedPattern = Identity로 변경하면 문제가 해결되었습니다. 감사합니다
tkt986

12

PK의 일부가 datetime 열이고 삽입 된 레코드가 DateTime.Now를 해당 열의 값으로 사용했기 때문에이 같은 오류가 발생했습니다. 엔터티 프레임 워크는 밀리 초 정밀도로 값을 삽입 한 다음 밀리 초 정밀도로 방금 삽입 한 값을 찾습니다. 그러나 SqlServer는 값을 두 번째 정밀도로 반올림하여 엔티티 프레임 워크가 밀리 초 정밀도 값을 찾을 수 없었습니다.

해결책은 삽입하기 전에 DateTime.Now에서 밀리 초를 자르는 것이 었습니다.


2
우리는에 삽입 된 것을 제외하고 우리는 같은 문제가 있었다 DateA를 열 DateTime
adam0101

1
여기도 마찬가지입니다. 우리는 데이터웨어 하우스 레코드를 가지고 있으며 타임 스탬프를 키의 일부로 사용하고있었습니다. 데이터웨어 하우스의 타임 스탬프는 SQL DateTime이지만 C #의 타임 스탬프는 일치하지 않습니다. SQL 데이터 유형을 DateTime2 (7)로 변경하고 EF 모델을 업데이트했으며 모두 수정되었습니다.
mmcfly

열을 Datetime2 (7)로 변경하면 나에게도 효과가있었습니다. 감사합니다 @mmcfly
Dzejms

10

나는 같은 문제가 있었고 @webtrifusion의 대답이 해결책 을 찾는 데 도움이되었습니다.

내 모델은 Bind(Exclude)엔티티 ID 의 속성을 사용하여 HttpPost에서 엔티티 ID 값이 0이되었습니다.

namespace OrderUp.Models
{
[Bind(Exclude = "OrderID")]
public class Order
{
    [ScaffoldColumn(false)]
    public int OrderID { get; set; }

    [ScaffoldColumn(false)]
    public System.DateTime OrderDate { get; set; }

    [Required(ErrorMessage = "Name is required")]
    public string Username { get; set; }
    }
}   

비슷한 문제로 보안상의 이유로 Bind (include = some fields)가 있습니다. ID가 목록에 없습니다. 또한 숨겨진 입력으로 추가했습니다. MVC에 의해 생성 된 것을 지웠거나 ID가 전혀 없었습니다. 도와 주셔서 감사합니다.
MusicAndCode

10

나는 똑같은 문제가 있었는데, 그것이 null 인 RowVersion으로 인한 것을 알았습니다. IDRowVersionnull아닌지 확인하십시오 .

자세한 내용은이 튜토리얼을 참조하십시오

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application


내 경우에는 행 버전이 null입니다
Prakash

제 경우에는 실수로 [Bind (Include = properties)]에서 ID 필드를 제거했습니다. 다시 추가하면 정상적으로 작동합니다.
Caverman

8

모델 우선에서 코드 우선으로 변경 한 후이 오류가 발생하기 시작했습니다. 일부는 동일한 행을 업데이트 할 수있는 데이터베이스를 업데이트하는 여러 스레드가 있습니다. 왜 모델 우선을 사용하는 데 문제가 없었는지 알 수 없으며 다른 동시성 기본값을 사용한다고 가정합니다.

발생할 수있는 조건을 알고있는 한 곳에서 처리하기 위해 DbContext 클래스에 다음 오버로드를 추가했습니다.

using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;

public class MyDbContext: DbContext {
...
        public int SaveChanges(bool refreshOnConcurrencyException, RefreshMode refreshMode = RefreshMode.ClientWins) {
            try {
                return SaveChanges();
            }
            catch (DbUpdateConcurrencyException ex) {
                foreach (DbEntityEntry entry in ex.Entries) {
                    if (refreshMode == RefreshMode.ClientWins)
                        entry.OriginalValues.SetValues(entry.GetDatabaseValues());
                    else
                        entry.Reload();
                }
                return SaveChanges();
            }
        }
}

그런 다음 SaveChanges(true)해당되는 곳에 전화하십시오.


1
좋아, 다른 사람들은이 문제에 대해 칭찬하면서 그들이 어떻게 그것을 유발시킬 수 있는지를 보여 주지만이 답변에는 멋진 답변이 있습니다. 나는 계속 업데이트 모델 (여기에는 저장 버튼이 없음)을 사용하고 EF 스레드가 뒤 떨어질 때 그리드 업데이트에서 이것을 얻었습니다. 내 좋은 이름을 훌륭하게 작동 시키십시오. 당신은 나를 영웅처럼 보이게했습니다-거인의 어깨에 서서!
Tony Trembath-Drake 7

너무 많은 옵션 -이 봐 나를 도왔 stackoverflow.com/a/13891724/4836581
즈비 Redler

7

기본 키의 BoundField를 명시 적으로 포함해야합니다. 사용자가 기본 키를 보지 못하게하려면 css를 통해 숨겨야합니다.

    <asp:BoundField DataField="Id_primary_key" ItemStyle-CssClass="hidden" 
HeaderStyle-CssClass="hidden" />

'hidden'은 CSS에서 클래스가 'none'으로 설정된 클래스입니다.


1
아, ASP.NET MVC에서 숨겨진 ID 필드를 삭제했다는 사실을 알게되었습니다. 감사합니다 @Paulo! :)
Tomasz Iniewicz 2018 년

7

편집하는 동안 엔티티의 ID 또는 기본 키를보기에서 숨겨진 필드로 포함

      @Html.HiddenFor(m => m.Id)

문제를 해결합니다.

또한 사용하지 않는 품목이 모델에 포함 된 경우 해당 품목도 포함하여 컨트롤러에 게시하십시오.


7

또한이 오류가 발생했습니다. 문제는 내가 저장하려는 테이블의 트리거로 인해 발생했습니다. 트리거는 'INSTEAD OF INSERT'를 사용하여 0 개의 행이 해당 테이블에 삽입되어 오류가 발생했음을 의미합니다. 운 좋게도 트리거 기능이 올바르지 않은 경우도 있지만 코드에서 처리해야하는 유효한 작업 일 수 있습니다. 이것이 언젠가 누군가를 돕기를 바랍니다.


2
트리거에서 SELECT 키 (기본 키 열 포함)를 리턴하여 행이 추가되었다고 믿도록 엔티티를 속일 수 있습니다.
jahu

1
@jahu의 주석을 확장하려면 새로 삽입 된 항목의 실제 ID를 트리거에서 반환해야하고 열 이름은 트리거 테이블의 ID 열과 일치해야합니다 (제 경우에는 실제로보기 '자체의 정체성은 없지만 edmx가 그것을 믿었다 고 속였습니다). 내 방아쇠는 별도의 테이블에 삽입을하고 있었으므로 방금 마지막 줄을 방아쇠에 추가했습니다.SELECT SCOPE_IDENTITY() as MyViewId
DannyMeister

또한이 질문을보십시오 : stackoverflow.com/questions/5820992/…
J. Polfer

필자의 경우 하위 컬렉션의 엔터티에서 삭제 작업을 수행했지만 다른 하위 엔터티가 삭제되는 하위 엔터티 중 하나에 대한 삭제 트리거가있었습니다. 엔티티 프레임 워크가 삭제하려고 시도하기 전에 하위 엔티티 자체 중 하나를 삭제하는 트리거로 인해 N-1 행이 영향을 받기 때문에 오류가 발생했습니다.
skeletank

6

기본 키가 누락되고 DATETIME (2, 3) 열이있는 테이블에서이 문제를 발견했습니다 (따라서 엔티티의 "기본 키"는 모든 열의 조합이었습니다) ... 삽입을 수행 할 때 타임 스탬프에는 더 정확한 시간 (2018-03-20 08 : 29 : 51.8319154)이 (2018-03-20 08 : 29 : 51.832)로 잘렸으므로 키 필드 조회가 실패합니다.


5

나는 또한이 오류가 있었다. 엔티티가 사용중인 실제 데이터베이스 컨텍스트를 인식하지 못하거나 모델이 다를 수있는 상황이 있습니다. 이를 위해 다음을 설정하십시오. EntityState.Modified; EntityState.Added에;

이것을하기 위해:

if (ModelState.IsValid)
{
context.Entry(yourModelReference).State = EntityState.Added;
context.SaveChanges();
}

이를 통해 기업은 귀하와 협력하고있는 주를 사용하거나 추가 할 수 있습니다. 이 시점에서 모든 올바른 모델 값을 설정해야합니다. 백그라운드에서 수행 된 변경 사항을 풀지 않도록주의하십시오.

도움이 되었기를 바랍니다.


1
당신은 전문가입니다! 그것은 나를 위해 작동합니다!
헤르 날도 곤잘레스

5
  @Html.HiddenFor(model => model.RowVersion)

내 rowversion이 null 이므로이 문제를 해결 한보기에 이것을 추가해야했습니다.


RowVersion을 View에서 편집 작업으로 전달하지 않았으며 RowVersion의 모델 바인딩을 잊어 버렸습니다. 오브젝트를 db에 저장할 때 동시성 검사를위한 오브젝트와 함께 이전 버전의 RowVersion 제출이 db에 제출되어야합니다. 일이 더 필요할 때 어리석은 실수를합니다!
Dhanuka777

5

[DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]내 경우에는 선 이 트릭을 수행했습니다.

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;


[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int? SomeNumber { get; set; }

4

표와 양식 모두 기본 키와 edmx를 업데이트했는지 확인하십시오.

내가 갱신하는 동안 오류가 때문에 보통의 사실을 발견하지 : - 테이블에 기본 키 - 편집보기 / 형태의 기본 키 (예를 @Html.HiddenFor(m=>m.Id)


4

나는 같은 문제가 있었다. 필자의 경우 기본 키를 업데이트하려고했지만 허용되지 않습니다.


4

async메소드를 사용할 때 산발적 으로이 오류가 발생했습니다 . 동기식 방법으로 전환 한 후 발생하지 않았습니다.

산발적으로 발생하는 오류 :

[Authorize(Roles = "Admin")]
[HttpDelete]
[Route("file/{id}/{customerId}/")]
public async Task<IHttpActionResult> Delete(int id, int customerId)
{
    var file = new Models.File() { Id = id, CustomerId = customerId };
    db.Files.Attach(file);
    db.Files.Remove(file);

    await db.SaveChangesAsync();

    return Ok();
}

항상 작동합니다 :

[Authorize(Roles = "Admin")]
[HttpDelete]
[Route("file/{id}/{customerId}/")]
public IHttpActionResult Delete(int id, int customerId)
{
    var file = new Models.File() { Id = id, CustomerId = customerId };
    db.Files.Attach(file);
    db.Files.Remove(file);

    db.SaveChanges();

    return Ok();
}

이로 인해 문제가 해결되었지만 PK 및 행 버전에 대한이 게시물의 앞부분에서 언급 한 근본적인 문제를 지적했습니다. PK가 명명 규칙을 따르지 않았기 때문에 더 복잡한 새 테이블에 대한 스키마 맵을 추가하지 않았습니다. <테이블 이름> ID.
midohioboarder

3

루프에서 DB의 일부 행을 삭제하고 동일한 테이블에 새 행을 추가 할 때 해당 오류가 발생했습니다.

나를위한 해결책은 각 루프 반복에서 새로운 컨텍스트를 동적으로 생성하는 것이 었습니다


나는 똑같은 일을해야했지만 왜 문제가 처음에 발생했는지 확실하지 않지만 이것은 효과가 있습니다.
제드 그랜트

3
    public void Save(object entity)
    {
        using (var transaction = Connection.BeginTransaction())
        {
        try
                {
                    SaveChanges();
                    transaction.Commit();
                }
                catch (OptimisticConcurrencyException)
                {
                    if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Deleted || ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Modified)
                        this.Refresh(RefreshMode.StoreWins, entity);
                    else if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Added)
                        Detach(entity);
                    AcceptAllChanges(); 
                    transaction.Commit();
                }
        }
    }

여기서 '이것'이 무엇을 의미하고 ObjectStateManager가 무엇인지 명확하게 설명해 주시겠습니까? 기본 리포지토리 클래스에서이 작업을 시도했지만 오류가 발생합니다.
Naomi

3

이는 고유 제약 조건에 삽입하려고 할 때도 발생합니다. 즉, 고용 주당 하나의 주소 유형 만 가질 수 있고 동일한 고용주에 동일한 유형의 두 번째 유형을 삽입하려고하면 동일한 문제가 발생합니다. .

또는

할당 된 모든 객체 속성이 이전과 동일한 값으로 할당 된 경우에도 발생할 수 있습니다.

        using(var db = new MyContext())
        {
            var address = db.Addresses.FirstOrDefault(x => x.Id == Id);

            address.StreetAddress = StreetAddress; // if you are assigning   
            address.City = City;                   // all of the same values
            address.State = State;                 // as they are
            address.ZipCode = ZipCode;             // in the database    

            db.SaveChanges();           // Then this will throw that exception
        }

2

edmx 파일에서 "함수 가져 오기"에 대한 맵핑을 작성하려고하면이 오류가 발생할 수 있습니다. edmx의 특정 엔티티에 대한 맵핑 세부 사항에있는 삽입, 업데이트 및 삭제 필드를 지우면 작동합니다. 나는 그것을 분명히하기를 바랍니다.


2

데이터베이스에 존재하지 않는 객체를 연결할 때이 예외가 발생했습니다. 객체가 별도의 컨텍스트에서로드되었다고 가정했지만 사용자가 사이트를 처음 방문한 경우 객체가 처음부터 만들어졌습니다. 자동 증분 기본 키가 있으므로 교체 할 수 있습니다.

context.Users.Attach(orderer);

if (orderer.Id > 0) {
    context.Users.Attach(orderer);
}

2

글쎄, 나는이 같은 문제가있다. 그러나 이것은 내 실수로 인한 것입니다. 실제로 나는 그것을 추가하는 대신 객체를 저장하고있었습니다. 그래서 이것은 갈등이었습니다.


2

Sql Server 환경에서이 문제를 디버깅하는 한 가지 방법은 SqlServer 사본에 포함 된 Sql Profiler를 사용하거나 Express 버전을 사용하는 경우 아래 링크를 통해 CodePlex에서 Express Profiler 사본을 무료로 얻는 것입니다.

익스프레스 프로파일 러

Sql Profiler를 사용하면 EF에서 DB로 보내는 모든 내용에 액세스 할 수 있습니다. 필자의 경우 이것은 다음과 같습니다.

exec sp_executesql N'UPDATE [dbo].[Category]
SET [ParentID] = @0, [1048] = NULL, [1033] = @1, [MemberID] = @2, [AddedOn] = @3
WHERE ([CategoryID] = @4)
',N'@0 uniqueidentifier,@1 nvarchar(50),@2 uniqueidentifier,@3 datetime2(7),@4 uniqueidentifier',
@0='E060F2CA-433A-46A7-86BD-80CD165F5023',@1=N'I-Like-Noodles-Do-You',@2='EEDF2C83-2123-4B1C-BF8D-BE2D2FA26D09',
@3='2014-01-29 15:30:27.0435565',@4='3410FD1E-1C76-4D71-B08E-73849838F778'
go

이것을 복사하여 Sql Server의 쿼리 창에 붙여 넣었습니다. 확실히 실행되었지만이 쿼리에 의해 0 개의 레코드가 영향을 받았으므로 EF에서 오류가 리턴됩니다.

필자의 경우 CategoryID로 인해 문제가 발생했습니다.

데이터베이스로 전송 된 ID EF로 식별 된 CategoryID가 없으므로 0 개의 레코드가 영향을받습니다.

이것은 EF의 잘못이 아니라 버그가있는 null 통합 "??" 넌센스를 데이터 계층으로 전송하는 View Controller에 표시합니다.


2

위의 답변 중 어느 것도 내 상황과 그에 대한 해결책을 다루지 않았습니다.

MVC5 컨트롤러에서 오류가 발생한 코드 :

        if (ModelState.IsValid)
        {
            db.Entry(object).State = EntityState.Modified; 
            db.SaveChanges(); // line that threw exception
            return RedirectToAction("Index");
        }

편집보기에서 객체를 저장할 때이 예외가 발생했습니다. 파일을 저장하기 위해 다시 돌아 왔을 때 객체의 기본 키를 구성하는 속성을 수정했기 때문입니다. 따라서 상태를 수정 됨으로 설정하는 것은 EF에 의미가 없었습니다. 이전에 저장된 항목이 아니라 새로운 항목이었습니다.

A) 객체 추가에 대한 저장 호출을 수정하거나 B) 편집시 기본 키를 변경하지 마십시오. 나는 B)했다.


2

받아 들여진 대답이 " 응용 프로그램이 알지 못했던 변경 사항을 덮어 쓰지 않을 것 "이라고 말했을 때 , 나는 객체가 새로 만들어 졌기 때문에 회의적이었습니다. 그러나 INSTEAD OF UPDATE, INSERT- TRIGGER동일한 테이블의 계산 된 열을 업데이트하는 테이블에 첨부 된 것으로 나타났습니다 .

이것을로 변경하면 AFTER INSERT, UPDATE정상적으로 작동했습니다.


2

이것은 datetime과 datetime2의 불일치로 인해 발생했습니다. 이상하게도 테스터가 문제를 발견하기 전에 제대로 작동했습니다. My Code First 모델에는 기본 키의 일부로 DateTime이 포함되었습니다.

[Key, Column(Order = 2)]  
public DateTime PurchasedDate { get; set; } = (DateTime)SqlDateTime.MinValue;

생성 된 열은 날짜 / 시간 열입니다. SaveChanges를 호출 할 때 EF는 다음 SQL을 생성했습니다.

-- Region Parameters
DECLARE @0 Int = 2
DECLARE @1 Int = 25
DECLARE @2 Int = 141051
DECLARE @3 DateTime2 = '2017-07-27 15:16:09.2630000' --(will not equal a datetime value)
-- EndRegion
UPDATE [dbo].[OrganizationSurvey]
SET [OrganizationSurveyStatusId] = @0
WHERE ((([SurveyID] = @1) AND ([OrganizationID] = @2)) AND ([PurchasedDate] = @3))

datetime 컬럼을 datetime2 값과 일치 시키려고했기 때문에 결과가 리턴되지 않았습니다. 내가 생각할 수있는 유일한 해결책은 열을 datetime2로 변경하는 것입니다.

[Key, Column(Order = 2, TypeName = "DateTime2")]  
public DateTime PurchasedDate { get; set; } = (DateTime)SqlDateTime.MinValue;

1
작동하지 않는 것과 작동하지 않는 것의 이상한 점은 기본 형식 /베이스 datetime와 관련이 datetime2있습니다. 본질적으로 일부 밀리 초 값은 일치하는 것으로 평가되고 다른 값은 그렇지 않습니다. 같은 일이 나에게 일어 났고 나는 또한로 바꿨다 DateTime2.
xr280xr

+1 나는 당신을 위해 이것에 +100 할 수 있기를 바랍니다. 나는 많은 곳을 둘러 본 후에 마침내 이것을 발견하고 실제로 기본 키의 일부로 Datetime을 가지고 있음을 깨달았습니다. 예, 이것은 실제로 해결되었습니다. 열을 Datetime2로 업데이트하고 작동했습니다. 이제 내 소고기는 Entity Framework를 사용 하여이 작업을 수행 해야하는 까다로운 쿼리를 고안했습니다.
Catchops
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.