나는 무엇을 해결하려면"행하지 않을 발견 또는 변경"예외 LINQ 에서 SQL 에 SQL Server Compact Edition 데이터베이스?

StackOverflow https://stackoverflow.com/questions/45045

  •  09-06-2019
  •  | 
  •  

문제

실행하는 경우 SubmitChanges 을 매핑되는 후 업데이트하는 몇 가지 특성으로 LINQ SQL 연결(에 대한 SQL Server Compact Edition)을 얻을"행 발견되지 않았거나 변경되었습니다." ChangeConflictException.

var ctx = new Data.MobileServerDataDataContext(Common.DatabasePath);
var deviceSessionRecord = ctx.Sessions.First(sess => sess.SessionRecId == args.DeviceSessionId);

deviceSessionRecord.IsActive = false;
deviceSessionRecord.Disconnected = DateTime.Now;

ctx.SubmitChanges();

쿼리를 생성하는 다음 SQL:

UPDATE [Sessions]
SET [Is_Active] = @p0, [Disconnected] = @p1
WHERE 0 = 1
-- @p0: Input Boolean (Size = 0; Prec = 0; Scale = 0) [False]
-- @p1: Input DateTime (Size = 0; Prec = 0; Scale = 0) [9/4/2008 5:12:02 PM]
-- Context: SqlProvider(SqlCE) Model: AttributedMetaModel Build: 3.5.21022.8

분명 문제입 0=1, 후에 기록되었는지,나는 것이 아니라는 것을 확인했 모든 속성에서"deviceSessionRecord"올바른를 포함합니다.또한 때 잡는"ChangeConflictException"거기에 대한 추가 정보를 왜 이하지 못했습니다.나 또한 확인되는 이 예외를 얻을 버려지는 정확히 하나의 레코드에 데이터베이스(기록이 나를 업데이트하려면)

무슨 이상한 매우 유사한 업데이트 문서의 다른 부분에 코드를 생성하는 다음 SQL 고 참으로 업데이트 내 SQL Server Compact Edition 데이터베이스입니다.

UPDATE [Sessions]
SET [Is_Active] = @p4, [Disconnected] = @p5
WHERE ([Session_RecId] = @p0) AND ([App_RecId] = @p1) AND ([Is_Active] = 1) AND ([Established] = @p2) AND ([Disconnected] IS NULL) AND ([Member_Id] IS NULL) AND ([Company_Id] IS NULL) AND ([Site] IS NULL) AND (NOT ([Is_Device] = 1)) AND ([Machine_Name] = @p3)
-- @p0: Input Guid (Size = 0; Prec = 0; Scale = 0) [0fbbee53-cf4c-4643-9045-e0a284ad131b]
-- @p1: Input Guid (Size = 0; Prec = 0; Scale = 0) [7a174954-dd18-406e-833d-8da650207d3d]
-- @p2: Input DateTime (Size = 0; Prec = 0; Scale = 0) [9/4/2008 5:20:50 PM]
-- @p3: Input String (Size = 0; Prec = 0; Scale = 0) [CWMOBILEDEV]
-- @p4: Input Boolean (Size = 0; Prec = 0; Scale = 0) [False]
-- @p5: Input DateTime (Size = 0; Prec = 0; Scale = 0) [9/4/2008 5:20:52 PM]
-- Context: SqlProvider(SqlCE) Model: AttributedMetaModel Build: 3.5.21022.8

제가 확인하는 적절한 기본 필드 값을 확인 모두에서 데이터베이스의 스키마와 DBML 생성하는 LINQ 클래스입니다.

난 이것은 거의 두 가지 부분은 질문:

  1. 왜 예외가 발생되는?
  2. 를 검토한 후,두 번째 세트의 생성 SQL,그것은 보인 충돌을 감지하는 좋은 것을 확인하는 모든 분야,하지만 내가 상상하는 것이 매우 비효율적이다.은 이 방법이 항상 작동하는지?가 설정을 확인하는 기본 키?

었으로 싸우는 이 두 시간 동안 그래서 어떤 도움을 감사하겠습니다.

도움이 되었습니까?

해결책

그게 불쾌하지만,간단하다:

체크인 경우에 데이터 유형에 대한 모든 분야에 O/R-디자이너 데이터 유형과 일치에서 SQL 테이블.에 대한 확인을 두 배로 널! 열어야 하고 널에서 모두 O/R-디자이너와 SQL,하거나 허용하지 않습니다.

예를 들어,이며 열에"제목은"으로 표시 널 데이터베이스에 포함되는 값은 NULL 입니다.지만 열이 없는 것으로 널에서 당신의 O/R-Mapping,LINQ 로드 그것을 성공적으로 설정하고 열 문자열은 null 입니다.

  • 지금은 뭔가 변경 및 통화 SubmitChanges().
  • LINQ 을 생성 SQL 쿼리 을 포함하는"여기서[제목]IS NULL"확인하기 위하여,제목 변경되지 않은 다른 누군가에 의해.
  • LINQ 이의 특성 [제목]에 매핑을 사용합니다.
  • LINQ 찾을 수 있[제목]입니다.
  • 이후[제목]null 을 허용하지 않에 의하여, 로직 그것은 결코 수 NULL!
  • 그래서 최적화,쿼리,LINQ 대체과 함께"어디에 0=1", SQL 에 해당""결코 없다.

동일한 증상이 나타납니다면 데이터의 유형의 분야 일치하지 않는 데이터의 유형에 SQL,는 경우 또는 필드가 누락되었기 때문 LINQ 수 없다는 것을 확인한 SQL 데이터 변경되지 않은 읽기 때문이다.

다른 팁

첫째로,그것은 유용한 알고,무엇이 문제를 일으킬 수 있습니다.인터넷 검색 솔루션을 도울 수 있습니 로그 정보(테이블,열,오래된 가치,새로운 값)에 대해 충돌을 찾은 더 나은 솔루션을 위한 충돌을 해결하상:

public class ChangeConflictExceptionWithDetails : ChangeConflictException
{
    public ChangeConflictExceptionWithDetails(ChangeConflictException inner, DataContext context)
        : base(inner.Message + " " + GetChangeConflictExceptionDetailString(context))
    {
    }

    /// <summary>
    /// Code from following link
    /// https://ittecture.wordpress.com/2008/10/17/tip-of-the-day-3/
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    static string GetChangeConflictExceptionDetailString(DataContext context)
    {
        StringBuilder sb = new StringBuilder();

        foreach (ObjectChangeConflict changeConflict in context.ChangeConflicts)
        {
            System.Data.Linq.Mapping.MetaTable metatable = context.Mapping.GetTable(changeConflict.Object.GetType());

            sb.AppendFormat("Table name: {0}", metatable.TableName);
            sb.AppendLine();

            foreach (MemberChangeConflict col in changeConflict.MemberConflicts)
            {
                sb.AppendFormat("Column name : {0}", col.Member.Name);
                sb.AppendLine();
                sb.AppendFormat("Original value : {0}", col.OriginalValue.ToString());
                sb.AppendLine();
                sb.AppendFormat("Current value : {0}", col.CurrentValue.ToString());
                sb.AppendLine();
                sb.AppendFormat("Database value : {0}", col.DatabaseValue.ToString());
                sb.AppendLine();
                sb.AppendLine();
            }
        }

        return sb.ToString();
    }
}

만들기 도우미가 배치를 위해 귀하의 sumbitChanges:

public static class DataContextExtensions
{
    public static void SubmitChangesWithDetailException(this DataContext dataContext)
    {   
        try
        {         
            dataContext.SubmitChanges();
        }
        catch (ChangeConflictException ex)
        {
            throw new ChangeConflictExceptionWithDetails(ex, dataContext);
        }           
    }
}

화한 다음 변경 내용을 전송할 때 사용하는 코드:

Datamodel.SubmitChangesWithDetailException();

마지막으로,로그를 제외에서 세계적인 예외 처리기:

protected void Application_Error(object sender, EventArgs e)
{         
    Exception ex = Server.GetLastError();
    //TODO
}

있는 방법에 매핑되는 불 새로고침 는 데 도움이 될 수 있습니다 여기에.그것은 당신이 다시의 데이터베이스 기록하기 전에 변경 내용을 제출하며,다양한 모드를 제공하는 값을 결정합니다."KeepChanges"보이는 똑똑한 내 목적을 위해,그것은 의도를 병합하는 나의 변경 내용과 어떤 충돌하지 않는 그 변경에서 일어난 데이터베이스에서 봅니다.

면을 이해하게 됩니다.:)

내가 이것을 해결 오류에 의해 redragging 통해 서버에서 테이블 탐색기의 디자이너와 다시 건물이다.

이할 수 있도를 사용하여 발생하는 하나 이상의 DbContext.

그래서 예를 들어:

protected async Task loginUser(string username)
{
    using(var db = new Db())
    {
        var user = await db.Users
            .SingleAsync(u => u.Username == username);
        user.LastLogin = DateTime.UtcNow;
        await db.SaveChangesAsync();
    }
}

protected async Task doSomething(object obj)
{
    string username = "joe";
    using(var db = new Db())
    {
        var user = await db.Users
            .SingleAsync(u => u.Username == username);

        if (DateTime.UtcNow - user.LastLogin >
            new TimeSpan(0, 30, 0)
        )
            loginUser(username);

        user.Something = obj;
        await db.SaveChangesAsync();
    }
}

이 코드 실패 시간,다는 점에서 예측할 수 없기 때문에,사용자 모두에 사용됩 컨텍스트로 변경하고 저장 하나,다음에 저장됩니다.메모리의 표현을 소유하는 사용자"Something"와 일치하지 않는 데이터베이스에서,그래서 당신이 숨어있는 버그입니다.

방법 중 하나 이를 방지하기 위한 코드를 작성할 수 있는 것이라고 라이브러리로 방법 같은 방법으로는 선택적 DbContext:

protected async Task loginUser(string username, Db _db = null)
{
    await EFHelper.Using(_db, async db =>
    {
        var user = await db.Users...
        ... // Rest of loginUser code goes here
    });
}

public class EFHelper
{
    public static async Task Using<T>(T db, Func<T, Task> action)
        where T : DbContext, new()
    {
        if (db == null)
        {
            using (db = new T())
            {
                await action(db);
            }
        }
        else
        {
            await action(db);
        }
    }
}

그래서 지금의 당신의 방법은 선택적인 데이터베이스,그리고 있지 않은 경우,간다고 한다.이 있는 경우는 그냥 재사용 무엇을 전달되었습니다.도우미는 방법은 쉽게 이것을 다시 사용 패턴에서의 응용이다.

내가 알지 못하는 경우에 당신은 발견하게 만족스러운 답변을 당신의 질문,하지만 나는 게시 비슷한 질문이고 결국 대답했습니다.는 것이 밝혀졌 NOCOUNT 기본 연결 옵션 설정에 대한 데이터베이스,발생 ChangeConflictException 에 대한 모든 업데이트로 만든 Linq to Sql.참조할 수 있습니다 내에서 게시물 .

나이에 의해 추가 (UpdateCheck = UpdateCheck.Never)[Column] 정의입니다.

하지 않는 것 같은 느낌 적절한 솔루션으로,하지만.내 경우에는 관련이 있을 것 같다는 사실이 테이블에 있는 협회를 다른 테이블이있는 곳에서 행 삭제됩니다.

이것은 Windows Phone7.5.

이것은 당신이 필요하여 이를 재정의 오류에 대 C#코드:

            try
            {
                _db.SubmitChanges(ConflictMode.ContinueOnConflict);
            }
            catch (ChangeConflictException e)
            {
                foreach (ObjectChangeConflict occ in _db.ChangeConflicts)
                {
                    occ.Resolve(RefreshMode.KeepChanges);
                }
            }

이 질문에는 오래전에 응답되었다 하지만 여기에 내가 마지막을 보냈다는 몇 시간을 두드리는 내 머리에 대하여 벽고 싶을 공유하는 솔루션으로 밝혀지에 관련된 모든 항목에서 이 실:

캐시!

선택()부분의 데이터를 객체를 캐싱 기능을 사용하.에 왔을 때 업데이트하는 개체의 행 발견되지 않았거나 변경한 오류를 자르다.

의 여러 가지 답변을 언급했을 사용하여 다른 매핑되고에서 돌이켜 보면 이것은 아마도 어떤 일이 일어나고 있었지만 그것이 없이 즉시 이끌어 나를 생각하는 캐싱을 그렇게 잘하면 이 도움이 될 것입니다 누군가가!

나는 최근에 이 오류가 발생한,그리고 문제점을 발견되지 않았으로 나 데이터의 컨텍스트,하지만 업데이트 문을 발사 내부 트리거 후 Commit 었다 호출되는 것이다.트리거하려고했던 업데이트 비 널 필드 null 값이 있는,그리고 그것을 일으키는 상황에 오류 메시지와 함께 위에서 언급된다.

추가하는 이 대답을 것을 돕기 위한 목적으로만 다른 사람이 다루는 오류를 발견하지 않음 해결책에 대한 답변니다.

또한 이 오류문을 사용하여 두 가지 다른 상황.내가 사용하여 이 문제는 단일 데이터의 컨텍스트입니다.

나의 케이스에서 문제가 있었으로 서버 사용자 옵션이 있습니다.다음과 같다:

https://msdn.microsoft.com/en-us/library/ms190763.aspx

나는 사용 NOCOUNT 옵션에서 희망을 얻는 몇 가지 성과 이득:

EXEC sys.sp_configure 'user options', 512;
RECONFIGURE;

이 밝혀 break Linq 의 검사에 대한 영향을 받은 행(로 내가 그것을 알아낼 수 있습니다.NET 원)도 ChangeConflictException

다시 설정 옵션을 제외 512 비트 고정 문제입니다.

사용 후 qub1n 의 대답이,내가 찾는 문제는 나를 위해 했 실수로 선언된 데이터베이스를 열을 진수(18,0).나는 할당 소수 값을 가지고 있지만,데이터베이스가 변경 제거,소수 부분입니다.이 행에서 변경된 문제입니다.

다만 이 경우 다른 사람이 실행으로 유사한 문제입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top