prosource

EntitySet에 DefiningQuery가 있고 요소가 없으므로 EntitySet을 업데이트할 수 없습니다.

probook 2023. 5. 3. 21:32
반응형

EntitySet에 DefiningQuery가 있고 요소가 없으므로 EntitySet을 업데이트할 수 없습니다.

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

다음과 같은 간단한 작업을 수행하고 있습니다.

var roomDetails = context.Rooms.ToList();

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

다음을 수행하려고 할 때 이 오류가 발생합니다.

 context.SaveChanges();

오류가 발생했습니다.

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

저는 컨텍스트에 대해 많은 업데이트를 하고 있지만 문제가 없습니다. 이 특정 엔티티를 업데이트하려고 할 때만 가능합니다.

업데이트하려는 엔티티에 선언된 기본 키가 없다는 검색 결과가 모두 동일하게 표시됩니다.하지만 안타깝게도, 기본 키가 선언되어 있습니다.

이 문제는 일반적으로 다음 이유 중 하나 때문에 발생합니다.

  • 엔티티 집합이 데이터베이스 보기에서 매핑되었습니다.
  • 사용자 정의 데이터베이스 조회
  • 데이터베이스 테이블에 기본 키가 없습니다.

이 작업을 수행한 후에도 오류가 발생하지 않도록 하려면 Entity Framework 디자이너에서 업데이트하거나 엔티티를 삭제한 후 추가해야 합니다.

기본 키를 테이블에 추가합니다.바로 그겁니다.문제는 해결됐습니다.

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

이것이 저의 경우입니다.제거하기만 하면 또 다른 오류가 발생했습니다.저는 마지막 게시물을 제외하고 이 게시물의 단계를 따랐습니다.당신의 편의를 위해 문제를 해결하기 위해 팔로우한 게시물의 4단계를 다음과 같이 복사했습니다.

  1. edmx 파일을 마우스 오른쪽 버튼으로 클릭하고 Open with, XML Editor를 선택합니다.
  2. edmx에서 엔티티를 찾습니다.스토리지 모델 요소
  3. 정의 쿼리를 완전히 제거합니다.
  4. 의 이름을 .store:Schema="dbo"Schema="dbo" 않다는

엔티티에는 기본 키가 있지만 데이터베이스테이블에는 기본 키가 없을 수 있습니다.

업데이트: 저는 최근에 이에 대한 몇 가지 찬성표를 얻었기 때문에 아래에 제시한 조언이 최선이 아니라는 것을 사람들에게 알리기로 했습니다.제가 처음에 오래된 키리스 데이터베이스에서 Entity Framework를 수행하는 것에 대해 고민하기 시작한 이후로, 지금까지 할 수 있는 최선의 방법은 코드 우선 역방향으로 수행하는 것이라는 것을 깨닫게 되었습니다.이것을 하는 방법에 대한 몇 가지 좋은 기사가 있습니다.따라서 키를 추가하려면 데이터 주석을 사용하여 키를 "가짜"로 만듭니다.

예를 들어, 내가 내 테이블을 안다고 가정해 보겠습니다.Orders기본 키는 없지만 고객당 하나의 주문 번호만 가질 수 있습니다. 두 첫

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

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

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

코드 우선 역방향 작업에 익숙하지 않은 경우 먼저 엔티티 프레임워크 코드 우선에 대한 좋은 튜토리얼을 찾아보십시오.그런 다음 역코드 우선(기존 데이터베이스로 코드 우선)에서 하나를 찾습니다.그럼 여기로 돌아와서 제 주요 조언을 다시 한 번 보세요.:)

원본 답변:

첫 번째: 다른 사람들이 말했듯이 가장 좋은 옵션은 테이블에 기본 키를 추가하는 것입니다.완전 정지.할 수 있으면 더 이상 읽지 마세요.

하지만 만약 여러분이 할 수 없거나 여러분 자신을 미워한다면, 기본 키 없이도 할 수 있는 방법이 있습니다.

저의 경우, 레거시 시스템(원래 Access로 포팅된 AS400의 플랫 파일을 T-SQL로 포팅함)으로 작업하고 있었습니다.그래서 방법을 찾아야 했습니다.이게 제 해결책입니다.다음은 Entity Framework 6.0(이 문서의 NuGet에 대한 최신 버전)을 사용하는 데 도움이 되었습니다.

  1. 솔루션 탐색기에서 .edmx 파일을 마우스 오른쪽 버튼으로 클릭합니다."열기..."를 선택한 후 "XML(텍스트) 편집기"를 선택합니다.우리는 여기서 자동 생성된 코드를 손으로 편집할 것입니다.

  2. : 다과같은음줄을찾다니습다니찾▁look▁like습.
    <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. : 이제선다같표이시됩다니과음은다▁now니표.
    <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이 제 기본 키라고 말했기 때문입니다.그래서 중복 주문을 제거하라고 했을 때 백그라운드에서 수행한 작업은 다음과 같습니다.

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

그리고 그 경고와 함께...당신은 이제 가도 좋습니다!

데이터 모델이 최신이 아닌 경우에도 이 문제가 발생할 수 있습니다.

바라건대 이것이 다른 누군가의 좌절을 덜어줄 것입니다 :)

키가했을 수 . 이 은 " 전용이고 "읽기 전용"입니다. "읽기 전용"입니다.db.SaveChanges ()명령은 항상 오류가 발생합니다.

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

다른 게시물을 보니 가입 테이블에 PK 필드를 추가해서 고칠 수 있을 것 같아서요...그러나 조인 테이블에 PK 열을 추가하면 더 이상 PJT가 아니며 엔티티 간의 자동 관계 매핑과 같은 엔티티 프레임워크 이점이 모두 손실됩니다.

그래서 제 경우 해결책은 DB의 조인 테이블을 변경하여 외부 ID 열을 모두 포함하는 PK를 만드는 것이었습니다.

Primary Key를 설정한 다음 Table을 저장하고 Refresh한 다음 Model.edmx delete Table로 이동하여 다시 가져옵니다.

사실입니다. 기본 키를 추가하십시오.

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

여기에 이미지 설명 입력

제 경우 테이블에 기본 키를 정의하는 것을 잊었습니다.따라서 그림에 표시된 것처럼 할당하고 .edmx 파일의 "데이터베이스에서 모델 업데이트"에서 표를 새로 고칩니다.그것이 도움이 되기를 바랍니다!!!

저도 같은 문제가 있었습니다.이 스레드에서 말한 것처럼 내 테이블에 PK가 없어서 PK를 설정하고 코드를 실행했습니다.하지만 불행히도 오류가 다시 발생했습니다.다음으로 DB 연결(솔루션 탐색기의 모델 폴더에서 .edmx 파일 삭제)을 삭제하고 다시 생성했습니다.그 후 오류가 사라졌습니다.여러분의 경험을 공유해 주셔서 감사합니다.그것은 많은 시간을 절약합니다.

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

USE [YourDatabaseName]
GO

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

기존 데이터베이스(다른 사용자가 설계했으며 여기서 '설계된'이라는 용어를 느슨하게 사용함)에서 EDMX를 생성하는 중이었기 때문에 이 문제가 발생했습니다.

알고 보니 그 테이블에는 열쇠가 전혀 없었습니다.EF는 여러 개의 키를 사용하여 모델을 생성하고 있었습니다.SQL의 DB 테이블에 기본 키를 추가하고 VS에서 모델을 업데이트해야 했습니다.

그것이 저를 위해 고쳐주었습니다.

기본 키를 추가하는 것도 효과가 있었습니다!

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

edmx Entity 디자이너 페이지와 '데이터베이스에서 모델 업데이트'를 마우스 오른쪽 버튼으로 클릭합니다.

저도 똑같은 문제가 있었는데, 안타깝게도 기본 키를 추가해도 문제가 해결되지 않습니다.내 문제를 해결하는 방법은 다음과 같습니다.

  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.

문제는 해결됐습니다.

기본 키를 테이블에 추가한 다음 EF를 다시 만듭니다.

저는 단지 모델에서 테이블을 제거하고 테이블을 다시 가져오면서 모델을 다시 업데이트해야 했습니다.기본 키는 테이블이 모델로 당겨진 후에 생성된 것 같습니다.

이 문제가 발생했는데, 테이블의 인덱스 기본 키를 삭제하고 테이블의 다른 필드의 인덱스로 바꾸었기 때문이라고 생각합니다.

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

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

이 문제를 해결하기 위해 EDMX를 열었을 때 기본 키가 정의되어 있는지 확인했습니다.그래서 위의 어떤 제안도 저에게 도움이 되지 않았습니다.그러나 기본 키의 인덱스를 새로 고치는 것은 효과가 있는 것처럼 보였습니다.

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

.edmx 파일 업데이트에 대한 원래 답변이 제 상황에 가장 적합하다는 것을 알게 되었습니다.저는 데이터베이스에서 모델이 업데이트될 때마다 모델을 변경하는 것이 그리 달갑지 않았습니다.그것이 제가 추가 텍스트 템플릿 파일을 작성한 이유입니다. 이 파일은 모델이 변경된 후 자동으로 호출됩니다. 마치 엔티티가 새로 생성된 것처럼 말입니다.제가 이 댓글에 올립니다.작동하려면 이름을 {modelname}(으)로 지정해야 합니다.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);
#>

저는 EF 프로젝트와 모든 클래스를 삭제하고 재구성하여 수정했습니다.자세한 내용은 아래를 참조하십시오.

저는 한 시간 동안 이것에 대해 빙글빙글 돌다가 오류가 포함된 EF 프로젝트를 삭제하고 모든 커스텀 코드를 저장한 다음 전체를 재구축했습니다.새로운 EF 다이어그램과 내부 코드를 생성하는 것만으로 문제가 발생했기 때문에 이 문제를 해결하는 데 약 10분이 걸렸습니다.

문제는 EF 클래스와 속성을 생성하는 데이터베이스 우선 방법이 두세 번 "업데이트"한 후에 약간 이상해진다는 것입니다.기본적으로 코드 동작에서 문제를 발견하고 데이터베이스 테이블 속성을 수정한 다음 EF 다이어그램을 너무 많이 업데이트했습니다.그런 다음 코드를 만지작거렸지만 작동하지 않았습니다.

일을 너무 많이 해서요.

언급URL : https://stackoverflow.com/questions/7583770/unable-to-update-the-entityset-because-it-has-a-definingquery-and-no-updatefu

반응형