DefiningQuery가 있고 <UpdateFunction> 요소가 없기 때문에 EntitySet을 업데이트 할 수 없습니다.


533

.net 3.5에서 Entity Framework 1을 사용하고 있습니다.

나는 이와 같은 간단한 일을하고있다 :

var roomDetails = context.Rooms.ToList();

foreach (var room in roomDetails)
{        
   room.LastUpdated = DateTime.Now;
}

시도 할 때이 오류가 발생합니다.

 context.SaveChanges();

오류가 발생합니다.

EntitySet을 업데이트 할 수 없습니다. DefiningQuery가 있고 현재 조작을 지원하기 위해 <ModificationFunctionMapping> 요소에 <UpdateFunction> 요소가 없기 때문에 EntitySet을 업데이트 할 수 없습니다.

컨텍스트에서 많은 업데이트를 수행하고 있으며 문제가 없습니다.이 특정 엔티티를 업데이트하려고 할 때만 발생합니다.

모든 검색에서 동일한 내용이 표시됩니다. 업데이트하려는 엔티티에 기본 키가 선언되어 있지 않습니다. 그러나 아아, 기본 키가 선언되어 있습니다 ...


61
실수했습니다. 식탁에 기본 키 세트가 없었습니다. 시간 내 주셔서 감사합니다! 불편을 드려 죄송합니다!
iKode

1
아마 기본 키 1000 개 테이블을 생성하고, 하나 잊어 - - 그냥 나에게 일어난 예외 메시지는 많은 도움이되지 않습니다
피터 Munnings

1
우수한. 실제로 테이블에 기본 키를 추가하는 것을 잊었습니다. 조심합시다)
AEMLoviji

답변:


1022

일반적으로 다음과 같은 이유로 발생합니다.

  • 엔티티 세트는 데이터베이스보기에서 맵핑됩니다.
  • 맞춤 데이터베이스 쿼리
  • 데이터베이스 테이블에 기본 키가 없습니다

이렇게 한 후에도 오류가 발생하기 전에 Entity Framework 디자이너에서 업데이트하거나 엔터티를 삭제 한 다음 추가해야 할 수도 있습니다.


2
여전히 문제가있는 경우 store : Schema를 해당 EntitySet에 대한 스키마로 변경해야합니다.
Geoff

53
그런 다음 EF 디자이너에서 업데이트가 제대로 작동하지 않으므로 엔티티를 삭제하고 다시 작성하십시오.
Suncat2000

48
PK가 답이었습니다. 감사!
nrod

1
데이터베이스에 기본 키를 추가 한 후 EF 디자이너의 업데이트가 제대로 작동했습니다. EF 5.0 및 .net 4.0 사용
StillLearnin

1
여기 동일합니다! Thx ... 테이블을 제거하고 EF에 다시 추가하여 테이블을
가져와야했습니다

90

테이블에 기본 키를 추가하십시오. 그게 다야. 문제 해결됨.

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

13
당신의 .edmx 파일을 "데이터베이스에서 업데이트 모델"을 클릭하는 것을 잊지 마세요
바샤 르 아부 Shamaa에게

@BasharAbuShamaa이 답변은 세부 사항이 없으면 유효하지 않습니다.
Kehlan Krumme

66

이것은 나를위한 경우입니다. 단순히 제거하면 다른 오류가 발생했습니다. 마지막 게시물을 제외하고이 게시물의 단계를 따랐습니다. 귀하의 편의를 위해 다음과 같이 게시물에서 4 단계를 복사하여 문제를 해결했습니다.

  1. edmx 파일을 마우스 오른쪽 단추로 클릭하고 연결 프로그램, XML 편집기를 선택하십시오.
  2. edmx : StorageModels 요소에서 엔티티를 찾으십시오.
  3. DefiningQuery를 완전히 제거하십시오.
  4. 이름 바꾸기 store:Schema="dbo"Schema="dbo"(그렇지 않으면 코드는 이름을 말하는 오류가 발생합니다 잘못되었습니다)

대단히 감사합니다. 이것이 바로 내 문제를 해결 한 것입니다. 이것이 EF에서 수정되지 않았다는 것을 상당히 혼란스럽게합니다. 그리고 당신이 이것을 알아 냈다는 것이 놀랍습니다!
자전거 Dave

엔터티를 삭제하고 다시 추가하려고했습니다. 재 컴파일. 청소. 이 외에는 아무것도 효과가 없었습니다.
Vintastic

1
이렇게하면 내 문제가 해결되었지만 답변을 어떻게 얻었는지, 제안으로 문제가 해결 된 이유를 모르겠습니다.
swcraft

데이터베이스 모델을 업데이트해야하는 경우 어떻게됩니까? "데이터베이스에서 모델 업데이트"를했는데 모델을 완전히 사용할 수 없게되었습니다. 취소하고 다시 시작해야했습니다. 이 주위에 방법이 있다면?
Gary

정말 이상한 문제입니다. 이 문제를 피하기 위해이 문제가 발생하는 방법에 대한 정보가 있습니까? 그럼에도 불구하고 - 그것은 도움이
r3dst0rm

41

그냥 어쩌면 당신의주의 엔티티는 기본 키 하지만 데이터베이스에 테이블 이없는 기본 키를 .


1
데이터베이스 테이블을 변경할 수없는 경우 극복하는 방법은 무엇입니까?
Kai Hartmann

기본 키를 갖도록 DB 테이블을 변경할 수있는 경우 코드 생성기는 동일한 실수를 중지하고 EF에서 키를 제거하면 다른 많은 문제가 발생합니다.
Chris Schaller

30

업데이트 : 최근에 이것에 대해 몇 가지 공감대를 얻었으므로 사람들이 내가 아래에 제공하는 조언이 최고가 아님을 알릴 것이라고 생각했습니다. 처음에는 오래된 키가없는 데이터베이스에서 Entity Framework를 수행하는 것에 대해 고민하기 시작했기 때문에 BY FAR로 할 수있는 최선의 방법은 코드 우선 역순으로 수행하는 것임을 알게되었습니다. 이 작업을 수행하는 방법에 대한 몇 가지 좋은 기사가 있습니다. 그냥 따르고 키를 추가하려면 데이터 주석을 사용하여 키를 "가짜"로 만드십시오.

예를 들어, 내 테이블을 알고 Orders있지만 기본 키는 없지만 고객 당 하나의 주문 번호 만 보장됩니다. 이것들은 테이블의 처음 두 열이기 때문에 다음과 같이 코드 첫 번째 클래스를 설정했습니다.

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

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

이렇게하면 주문 번호와 고객으로 구성된 클러스터 된 키가 있다고 믿기 위해 기본적으로 EF를 위조합니다. 이를 통해 키가없는 테이블에서 삽입, 업데이트 등을 수행 할 수 있습니다.

리버스 코드 우선 작업에 익숙하지 않은 경우 Entity Framework Code First에 대한 유용한 자습서를 찾아보십시오. 그런 다음 Reverse Code First (기존 데이터베이스에서 Code First)를 수행하십시오. 그런 다음 여기로 돌아와서 나의 주요 조언을 다시보십시오. :)

원래 답변 :

첫째 : 다른 사람들이 말했듯이 가장 좋은 방법은 기본 키를 테이블에 추가하는 것입니다. 마침표. 이 작업을 수행 할 수 있으면 더 이상 읽지 마십시오.

그러나 자신을 미워할 수 없거나 미워한다면 기본 키없이 할 수있는 방법이 있습니다.

필자의 경우, 레거시 시스템 (원래 AS400의 플랫 파일은 Access로 포트 된 다음 T-SQL로 포트 된 파일)로 작업하고있었습니다. 그래서 나는 길을 찾아야했다. 이것이 나의 해결책이다. 다음은 Entity Framework 6.0 (이 글을 쓰는 시점에서 NuGet의 최신 버전)을 사용하여 나를 위해 일했습니다.

  1. 솔루션 탐색기에서 .edmx 파일을 마우스 오른쪽 버튼으로 클릭하십시오. "연결 프로그램 ..."을 선택한 다음 "XML (텍스트) 편집기"를 선택하십시오. 여기서 자동 생성 된 코드를 직접 편집 할 것입니다.

  2. 다음과 같은 줄을 찾으십시오.
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" store:Schema="dbo" store:Name="table_nane">

  3. store:Name="table_name"끝에서 제거하십시오 .

  4. 변경 store:Schema="whatever"Schema="whatever"

  5. 해당 줄 아래를보고 <DefiningQuery>태그를 찾으십시오 . 그것에 큰 ol 'select 문이있을 것입니다. 태그와 내용을 제거하십시오.

  6. 이제 라인은 다음과 같아야합니다.
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />

  7. 우리는 바꿀 다른 것이 있습니다. 파일을 살펴보고 이것을 찾으십시오.
    <EntityType Name="table_name">

  8. 근처에는 기본 키가 없다는 경고 텍스트가 표시 될 수 있으므로 키가 유추되었으며 정의는 읽기 전용 테이블 / 뷰입니다. 그대로 두거나 삭제할 수 있습니다. 삭제했습니다.

  9. 아래는 <Key>태그입니다. 이것이 Entity Framework가 삽입 / 업데이트 / 삭제를 수행하는 데 사용하는 것입니다. 따라서 귀하가이 권리를 준수하는지 확인하십시오. 해당 태그의 속성은 고유하게 식별 가능한 행을 나타내야합니다. 예를 들어, 내 테이블을 알고 orders있지만 기본 키는 없지만 고객 당 하나의 주문 번호 만 보장됩니다.

그래서 내 모습은 다음과 같습니다.

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

진지하게, 이것을 잘못하지 마십시오. 중복이 없어야하더라도 주문 번호와 고객 이름이 동일한 두 개의 행이 내 시스템에 들어갑니다. 으악! 그것이 열쇠를 사용하지 않아 얻는 것입니다! 따라서 Entity Framework를 사용하여 하나를 삭제합니다. 오늘 중복 주문이 유일한 주문임을 알고 있으므로 다음과 같이하십시오.

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

뭔지 맞춰봐? 방금 복제본과 원본을 모두 삭제했습니다! Entity Framework에 order_number / cutomer_name이 기본 키라고 말했기 때문입니다. 따라서 duplicateOrder를 제거하라고 말했을 때 백그라운드에서 수행 한 작업은 다음과 같습니다.

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

그리고 그 경고와 함께 ... 이제 가야합니다!


문제에 대한 동일한 해결책을 찾은 후이 답변을 찾았습니다. 정답입니다! 다른 답변에서 언급 한 것처럼 기본 키만 정의해도 도움이되지 않습니다.
Obl Tobl

19

데이터 모델이 오래된 경우에도 발생할 수 있습니다.

잘하면 이것은 다른 누군가를 좌절시킬 것입니다 :)


6

동일한 오류 메시지가 표시되었지만 시나리오에서 PJT (Pure Join Table)를 사용하여 다 대다 관계에서 파생 된 엔티티를 업데이트하려고했습니다.

다른 게시물을 읽었을 때 조인 테이블에 추가 PK 필드를 추가하여 문제를 해결할 수 있다고 생각했습니다. 그러나 조인 테이블에 PK 열을 추가하면 더 이상 PJT가 아니므로 더 이상 PJT가 아닙니다. 엔티티 간의 자동 관계 맵핑과 같은 엔티티 프레임 워크의 장점.

그래서 내 경우의 해결책은 DB의 조인 테이블을 변경하여 외래 ID 열의 BOTH를 포함하는 PK를 만드는 것입니다.


이것이 EDMX 생성이 항상 효과가 있었습니까? 순수한 조인 테이블에서 PK가 필요없는 Code First로 작업하는 데 익숙합니다.
Michael Hornfeck

4

테이블에 기본 키가없는 경우 오류가 발생할 수 있습니다.이 경우 테이블은 "읽기 전용"이며 db.SaveChanges () 명령은 항상 오류를 발생시킵니다.


4

기본 키를 설정 한 다음 테이블 및 새로 고침을 저장 한 다음 Model.edmx delete Table로 이동하여 다시 가져 오십시오.


3

사실, 기본 키를 추가하십시오.

참고 : 올바른 데이터베이스를 가리키는 데이터베이스에서 EF 다이어그램을 업데이트 할 때 연결 문자열이 최신 Dev DB 대신 로컬 DB를 가리키고 있는지 확인하십시오. 내가 아는 오류이지만 기본 키를 추가했는데 여전히 동일한 오류가 발생한다고 확신하면 매우 실망 스러울 수 있기 때문에 이것을 게시하고 싶었습니다.


2

나는 같은 문제가 있었다. 이 스레드가 말했듯이 내 테이블에는 PK가 없으므로 PK를 설정하고 코드를 실행했습니다. 그러나 불행히도 오류가 다시 발생했습니다. 다음으로 DB 연결을 삭제하고 (솔루션 탐색기의 Model 폴더에서 .edmx 파일 삭제) 다시 작성했습니다. 그 후 오류가 발생했습니다. 경험을 공유해 주셔서 감사합니다. 시간이 많이 절약됩니다.


1

기존 데이터베이스에서 EDMX를 생성했기 때문에이 문제가 발생했습니다.

테이블에 키가 없었습니다. EF는 여러 개의 키가 많은 모델을 생성했습니다. SQL의 db 테이블에 기본 키를 추가 한 다음 VS에서 모델을 업데이트해야했습니다.

그것은 나를 위해 그것을 고쳤다.


1

이것은 새로운 대답은 아니지만 테이블의 기본 키를 설정하는 방법을 모르는 사람에게 도움이 될 것입니다. 이것을 새로운 쿼리에서 사용하고 실행하십시오. UniqueID 열을 기본 키로 설정합니다.

USE [YourDatabaseName]
GO

Alter table  [dbo].[YourTableNname]
Add Constraint PK_YourTableName_UniqueID Primary Key Clustered (UniqueID);
GO

1

여기에 이미지 설명을 입력하십시오

필자의 경우 기본 키를 테이블로 정의하는 것을 잊었습니다. 따라서 그림과 같이 지정하고 .edmx 파일의 "데이터베이스에서 모델 업데이트"에서 테이블을 새로 고치십시오. 그것이 도움이되기를 바랍니다!


0

기본 키를 추가해도 나에게 도움이되었습니다!

완료되면 데이터 모델을 삭제하지 않고 업데이트하는 방법은 다음과 같습니다.

edmx 엔터티 디자이너 페이지와 '데이터베이스에서 모델 업데이트'를 마우스 오른쪽 버튼으로 클릭하십시오.


0

불행히도 기본 키를 추가해도 문제가 해결되지 않습니다. 다음은 내가 어떻게 해결합니까?

  1. 확실히 당신은이 있는지 확인 primary key내 테이블을 변경하고 기본 키를 추가 할 수 있도록 테이블에.
  2. Delete the ADO.NET Entity Data Model (edmx 파일) 데이터베이스를 매핑하고 연결하는 데 사용합니다.
  3. Add again a new file of ADO.NET Entity Data Model 데이터베이스에 연결하고 모델 속성을 매핑합니다.
  4. Clean and rebuild the solution.

문제 해결됨.


0

테이블에 기본 키를 추가 한 다음 EF를 다시 만드십시오.


0

방금 모델에서 테이블을 제거하고 모델을 다시 업데이트하여 테이블을 다시 가져와야했습니다. 테이블을 모델로 가져온 후 기본 키가 생성 된 것 같습니다.


0

이 문제가 발생하여 테이블의 기본 키에서 인덱스를 삭제하고 테이블의 다른 필드 중 일부의 인덱스로 대체했기 때문에 발생했다고 생각합니다.

기본 키 인덱스를 삭제하고 edmx를 새로 고친 후 삽입 작업이 중지되었습니다.

테이블을 이전 버전으로 새로 고치고 edmx를 새로 고치면 모든 것이 다시 작동합니다.

이 문제를 해결하기 위해 EDMX를 열었을 때 기본 키가 정의되어 있는지 확인했습니다. 따라서 위의 제안 중 어느 것도 나를 도와주지 않았습니다. 그러나 기본 키의 인덱스를 새로 고치는 것이 효과가있는 것 같습니다.


0

XML 편집기에서 .edmx 파일을 연 다음 태그에서 태그를 제거하고 store : Schema = "dbo"를 Schema = "dbo"로 변경하고 이제 솔루션을 다시 빌드하면 오류가 해결되고 데이터를 저장할 수 있습니다.


0

내 상황에서 .edmx 파일을 업데이트하는 원래의 대답이 가장 효과적이라는 것을 알았습니다. 데이터베이스에서 업데이트 될 때마다 모델을 변경하는 것에 너무 만족하지 않았습니다. 그렇기 때문에 엔터티가 새로 생성 된 것처럼 모델이 변경된 후 자동으로 호출되는 추가 텍스트 템플릿 파일을 작성했습니다. 나는이 의견에 여기에 게시합니다. 작동하려면 {model name} .something.tt와 같이 이름을 지정하고 .edmx 폴더와 동일한 폴더에 저장하십시오. 이름을 {model name} .NonPkTables.tt로 지정했습니다. 두 번째 행에서 유효하지 않은 파일 확장자 정의로 인해 자체적으로 파일을 생성하지 않습니다. 자유롭게 사용하십시오.

<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ output extension="/" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Data" #>
<#@ assembly name="System.Windows.Forms" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="System.Xml.Linq"#>
<#@ assembly name="%VS120COMNTOOLS%..\IDE\EntityFramework.dll" #>
<#@ assembly name="%VS120COMNTOOLS%..\IDE\Microsoft.Data.Entity.Design.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Windows.Forms" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Xml.Linq" #>
<#@ import namespace="System.Globalization" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Data.Entity.Core.Metadata.Edm" #>
<#@ import namespace="System.Data.Entity.Core.Mapping" #>
<#@ import namespace="System.CodeDom" #>
<#@ import namespace="System.CodeDom.Compiler" #>
<#@ import namespace="Microsoft.CSharp"#>
<#@ import namespace="System.Text"#>
<#@ import namespace="System.Diagnostics" #>

<#
    string modelFileName= this.Host.TemplateFile.Split('.')[0] + ".edmx";
    string edmxPath = this.Host.ResolvePath( modelFileName );

    // MessageBox.Show( this.Host.TemplateFile + " applied." );
    var modelDoc = XDocument.Load(edmxPath);
    var root = modelDoc.Root;
    XNamespace nsEdmx = @"http://schemas.microsoft.com/ado/2009/11/edmx";
    XNamespace ns = @"http://schemas.microsoft.com/ado/2009/11/edm/ssdl";

    var runtime = root.Elements(nsEdmx + "Runtime").First();
    var storageModels = runtime.Elements(nsEdmx + "StorageModels").First();
    XNamespace nsStore = @"http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator";

    var schema = storageModels.Elements(ns + "Schema").First();
    XNamespace nsCustomAnnotation = @"http://schemas.microsoft.com/ado/2013/11/edm/customannotation";

    var entityTypes = schema.Nodes().OfType<XComment>().Where(c => c.Value.Contains("warning 6002: The table/view"));
    bool changed = false;

    foreach (var node in entityTypes)
    {
        var element = node.ElementsAfterSelf().First();
        string entityName = element.Attribute("Name").Value;

        // Find EntitySet in EntityContainer.
        var entityContainer = schema.Elements(ns + "EntityContainer").First();
        var entitySet = entityContainer.Elements(ns + "EntitySet").First(s => s.Attribute("Name").Value == entityName);

        // Change "store:Schema" attribute to "Schema" attribute.
        var attribute = entitySet.Attribute(nsStore + "Schema");

        if (attribute != null)
        {
            string schemaName = entitySet.Attribute(nsStore + "Schema").Value;
            entitySet.Attribute(nsStore + "Schema").Remove();
            entitySet.Add(new XAttribute("Schema", schemaName));
            changed |= true;
        }

        // Remove the DefiningQuery element.
        var definingQuery = entitySet.Element(ns + "DefiningQuery");

        if (definingQuery != null)
        {
            definingQuery.Remove();
            changed |= true;        
            Debug.WriteLine(string.Format("Removed defining query of EntitySet {0}.", entityName));
        }
    }

    if (changed)
        modelDoc.Save(edmxPath);
#>

-1

내가 가진 테이블의 레코드 삽입과 같은 오류 메시지가 직면 다 대다 관계를. 내 데이터베이스 스키마는 다음과 같습니다.

Student (Id , Name)
Course (Code , Title),
Student-Course (Student_ID, Course_Code)

테이블 StudentCourse 에는 기본 키 Id 및 Code가 각각 있고 Student-Course 테이블 에는 Student 및 Course 테이블과 매핑 된 두 개의 외래 키가 있습니다.

논리적으로 스키마는 정확하지만 모든 테이블에 기본 키가 있어야하기 때문에 데이터베이스에서 실수했습니다.

Student-Course 에 대한 내 SQL 정의 는 다음과 같습니다.

CREATE TABLE [dbo].[Student-Course] (
    [StudentID]  VARCHAR (12) NOT NULL,
    [CourseCode] VARCHAR (10) NOT NULL,
    CONSTRAINT [FK_Student-Course_ToCourse] FOREIGN KEY ([Course_Code]) REFERENCES [dbo].[Course] ([Code]) ON DELETE CASCADE,
    CONSTRAINT [FK_Student-Course_ToStudent] FOREIGN KEY ([Student_ID]) REFERENCES [dbo].[Student] ([Id]) ON DELETE CASCADE
);

외래 키 쌍을이 테이블의 기본 키로 만들고 다음으로 업데이트했습니다.

CREATE TABLE [dbo].[Student-Course] (
    [StudentID]  VARCHAR (12) NOT NULL,
    [CourseCode] VARCHAR (10) NOT NULL,
    CONSTRAINT [PK_Student-Course] PRIMARY KEY CLUSTERED ([Student_ID] ASC, [Course_Code] ASC),
    CONSTRAINT [FK_Student-Course_ToCourse] FOREIGN KEY ([Course_Code]) REFERENCES [dbo].[Course] ([Code]) ON DELETE CASCADE,
    CONSTRAINT [FK_Student-Course_ToStudent] FOREIGN KEY ([Student_ID]) REFERENCES [dbo].[Student] ([Id]) ON DELETE CASCADE
);

그것이 일부 사람들의 문제를 해결할 수 있기를 바랍니다.


이 질문에는 이미 너무 많은 답변이 있습니다. 또한, 거의 각 대답은 "기본 키를 추가"라고하고 하나 다 대다의 맥락에서 그것을 않습니다.
Gert Arnold

당신은 옳지 만, 어떤 사람들 은 세 번째 테이블에 여분의 기본 키 ID 를 추가합니다 .
Summar Raja

다른 답변도 말합니다.
Gert Arnold
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.