ไม่สามารถอัปเดต EntitySet - เนื่องจากมี DefiningQuery และไม่มีองค์ประกอบ <UpdateFunction> อยู่


533

ฉันใช้ Entity Framework 1 กับ. net 3.5

ฉันกำลังทำอะไรง่ายๆแบบนี้:

var roomDetails = context.Rooms.ToList();

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

ฉันได้รับข้อผิดพลาดนี้เมื่อพยายามทำ:

 context.SaveChanges();

ฉันได้รับข้อผิดพลาด:

ไม่สามารถอัปเดต EntitySet - เนื่องจากมี DefiningQuery และไม่มีองค์ประกอบ <UpdateFunction> ในองค์ประกอบ <ModificationFunctionMapping> เพื่อรองรับการทำงานปัจจุบัน

ฉันกำลังอัปเดตจำนวนมากเกี่ยวกับบริบทและไม่มีปัญหาใด ๆ เกิดขึ้นเมื่อฉันพยายามอัปเดตเอนทิตีเฉพาะนี้เท่านั้น

การค้นหาทั้งหมดของฉันปรากฏในสิ่งเดียวกันว่าไม่มีคีย์หลักที่ประกาศในเอนทิตีที่ฉันพยายามอัปเดต แต่อนิจจาฉันมีคีย์หลักที่ประกาศ ...


61
ฉันทำผิดพลาดไม่มีคีย์หลักตั้งอยู่บนโต๊ะขอบคุณสำหรับเวลาของคุณ! ขออภัยในความไม่สะดวก!
iKode

1
เพิ่งเกิดขึ้นกับฉัน - อาจสร้าง 1,000 ตารางด้วยคีย์หลักและลืม - ข้อความข้อยกเว้นไม่ได้ช่วยอะไรมาก
Peter Munnings

1
ยอดเยี่ยม จริงๆฉันลืมที่จะเพิ่มคีย์หลักในตาราง ลองระวังให้ดี)
AEMLoviji

คำตอบ:


1022

มันมักจะเกิดขึ้นเพราะหนึ่งในเหตุผลต่อไปนี้:

  • ชุดเอนทิตีถูกแมปจากมุมมองฐานข้อมูล
  • แบบสอบถามฐานข้อมูลที่กำหนดเอง
  • ตารางฐานข้อมูลไม่มีคีย์หลัก

หลังจากทำเช่นนั้นคุณอาจต้องอัปเดตในตัวออกแบบ Entity Framework (หรือลบเอนทิตีแล้วเพิ่มเข้าไป) ก่อนที่คุณจะหยุดรับข้อผิดพลาด


2
อย่าลืมเปลี่ยน store: Schema เป็น Schema สำหรับ EntitySet นั้นถ้าคุณยังมีปัญหาอยู่
Geoff

53
จากนั้นลบและสร้างเอนทิตีใหม่เนื่องจากการอัปเดตไม่ทำงานในตัวออกแบบของ EF
Suncat2000

48
PK คือคำตอบ ขอบคุณ!
nrod

1
อัพเดทในตัวออกแบบของ EF ทำงานได้ดีสำหรับฉันหลังจากเพิ่มคีย์หลักในฐานข้อมูล ใช้ EF 5.0 และ. net 4.0
StillLearnin

1
กันที่นี่! ขอบคุณ ... ต้องลบตารางและเพิ่มใน EF เพื่อรับมันอีกครั้ง
ajzeffer

90

เพียงเพิ่มคีย์หลักลงในตาราง แค่นั้นแหละ. แก้ไขปัญหา.

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

13
และอย่าลืมคลิกที่ "อัปเดตโมเดลจากฐานข้อมูล" ในไฟล์. edmx ของคุณ
Bashar Abu Shamaa

@BasharAbuShamaa คำตอบนี้ไม่ถูกต้องหากไม่มีรายละเอียดนั้น
Kehlan Krumme

66

นี่เป็นกรณีสำหรับฉัน เพียงแค่ลบออกทำให้เกิดข้อผิดพลาดอื่น ฉันทำตามขั้นตอนของโพสต์นี้ยกเว้นโพสต์สุดท้าย เพื่อความสะดวกของคุณฉันได้คัดลอก 4 ขั้นตอนจากโพสต์ที่ฉันติดตามเพื่อแก้ไขปัญหาดังต่อไปนี้:

  1. คลิกขวาที่ไฟล์ edmx เลือกเปิดด้วยตัวแก้ไข XML
  2. ค้นหาเอนทิตีในองค์ประกอบ edmx: StorageModels
  3. ลบ DefiningQuery ทั้งหมด
  4. เปลี่ยนชื่อstore:Schema="dbo"ไปSchema="dbo"(มิฉะนั้นรหัสจะสร้างข้อผิดพลาดว่าชื่อไม่ถูกต้อง)

ขอบคุณมาก - นี่คือสิ่งที่แก้ไขปัญหาของฉัน ค่อนข้างรำคาญว่าสิ่งนี้ไม่ได้รับการแก้ไขใน EF และน่าทึ่งมากที่คุณคิดออก!
จักรยาน Dave

ฉันพยายามลบเอนทิตีและเพิ่มอีกครั้ง recompiling การทำความสะอาด ไม่มีอะไรทำงานให้ฉันยกเว้นสิ่งนี้
vintastic

1
วิธีนี้แก้ไขปัญหาของฉันได้ แต่ฉันไม่รู้ว่าคุณคิดอย่างไรกับคำตอบและทำไมข้อเสนอแนะของคุณจึงแก้ไขปัญหา
swcraft

จะเกิดอะไรขึ้นหากคุณต้องการอัปเดตโมเดลฐานข้อมูล ฉันทำ "อัปเดตโมเดลจากฐานข้อมูล" และทำให้โมเดลของฉันใช้ไม่ได้โดยสิ้นเชิง ฉันต้องยกเลิกและเริ่มต้นใหม่อีกครั้ง หากมีวิธีแก้ไขปัญหานี้
แกรี่

นั่นเป็นปัญหาที่แปลกจริงๆ มีข้อมูลใด ๆ เกี่ยวกับปัญหาที่เกิดขึ้นเพื่อหลีกเลี่ยงหรือไม่ กระนั้น - มันช่วย
r3dst0rm

41

ทราบเพียงว่าบางทีคุณEntity มีคีย์หลักแต่ตารางของคุณในฐานข้อมูลไม่ได้มีคีย์หลัก


1
วิธีการเอาชนะถ้าเราไม่สามารถเปลี่ยนตารางฐานข้อมูลหรือไม่
Kai Hartmann

หากคุณสามารถเปลี่ยนตาราง DB เป็นคีย์หลักได้ตัวสร้างโค้ดจะหยุดทำผิดพลาดเหมือนเดิมการลบคีย์ออกจาก EF จะทำให้เกิดปัญหาอื่น ๆ อีกมากมาย
Chris Schaller

30

อัปเดต:ฉันเพิ่งได้รับการอัปเดตไม่กี่ครั้งเมื่อเร็ว ๆ นี้ดังนั้นฉันจึงคิดว่าฉันจะให้คนอื่นรู้ว่าคำแนะนำที่ฉันให้ไว้ด้านล่างไม่ใช่สิ่งที่ดีที่สุด ตั้งแต่แรกเริ่มที่ฉันเริ่มทำ Entity Framework บนฐานข้อมูลแบบไม่มีกุญแจฉันรู้ว่าสิ่งที่ดีที่สุดที่คุณสามารถทำได้โดย FAR นั้นทำได้โดยย้อนกลับโค้ดแรก มีบทความดีๆอยู่สองสามข้อเกี่ยวกับวิธีการทำเช่นนี้ เพียงทำตามพวกเขาและจากนั้นเมื่อคุณต้องการที่จะเพิ่มที่สำคัญกับมันคำอธิบายประกอบการใช้ข้อมูลเพื่อ "ปลอม" ที่สำคัญ

ตัวอย่างเช่นสมมติว่าฉันรู้ตารางของฉันOrdersในขณะที่ไม่มีคีย์หลักมั่นใจได้ว่าจะมีเพียงหมายเลขคำสั่งซื้อเดียวต่อลูกค้า เนื่องจากสิ่งเหล่านี้เป็นสองคอลัมน์แรกในตารางฉันจึงตั้งค่ารหัสชั้นเรียนแรกให้มีลักษณะดังนี้:

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

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

โดยการทำเช่นนี้คุณจะแกล้งทำให้ EF เชื่อว่ามีคีย์กลุ่มที่ประกอบด้วย OrderNumber และลูกค้า สิ่งนี้จะช่วยให้คุณสามารถแทรกการอัพเดทและอื่น ๆ บนโต๊ะของคุณ

หากคุณไม่คุ้นเคยกับการทำ Reverse Code First ให้ไปหาบทช่วยสอนที่ดีเกี่ยวกับ Entity Framework Code First จากนั้นไปหาหนึ่งรายการใน Reverse Code First (ซึ่งกำลังทำ Code First กับฐานข้อมูลที่มีอยู่) จากนั้นกลับมาที่นี่และดูคำแนะนำที่สำคัญของฉันอีกครั้ง :)

คำตอบเดิม :

ข้อแรก: อย่างที่คนอื่น ๆ พูดไว้ตัวเลือกที่ดีที่สุดคือการเพิ่มคีย์หลักลงในตาราง หยุดเต็ม หากคุณสามารถทำได้อ่านไม่เพิ่มเติม

แต่ถ้าคุณทำไม่ได้หรือแค่เกลียดตัวเองก็มีวิธีที่จะทำโดยไม่มีคีย์หลัก

ในกรณีของฉันฉันทำงานกับระบบดั้งเดิม (เดิมคือไฟล์แฟล็ตบน AS400 ที่ส่งไปยัง Access แล้วพอร์ตไปยัง T-SQL) ดังนั้นฉันต้องหาวิธี นี่คือทางออกของฉัน ต่อไปนี้ใช้งานได้สำหรับฉันโดยใช้ Entity Framework 6.0 (ล่าสุดบน NuGet จากการเขียนนี้)

  1. คลิกขวาที่ไฟล์. edmx ของคุณใน Solution Explorer เลือก "เปิดด้วย ... " จากนั้นเลือก "ตัวแก้ไข 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 ขนาดใหญ่ในนั้น ลบแท็กและเนื้อหา

  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>

อย่างจริงจังอย่าทำสิ่งนี้ผิด สมมติว่าแม้ว่าจะไม่ซ้ำกัน แต่อย่างใดสองแถวเข้าสู่ระบบของฉันด้วยหมายเลขคำสั่งซื้อและชื่อลูกค้าเดียวกัน Whooops! นั่นคือสิ่งที่ฉันได้รับโดยไม่ใช้กุญแจ! ดังนั้นฉันจึงใช้ 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)

และด้วยคำเตือนนั้น ... ตอนนี้คุณน่าจะไปได้ดี!


พบคำตอบนี้หลังจากค้นหาวิธีแก้ไขปัญหาเดียวกัน คำตอบที่ถูกต้องแน่นอน! การกำหนดคีย์หลักเช่นเดียวกับที่กล่าวถึงในคำตอบอื่น ๆ จะไม่ช่วยในหลายกรณี
Obll Tobl

19

สิ่งนี้สามารถเกิดขึ้นได้หากตัวแบบข้อมูลล้าสมัย

หวังว่านี่จะช่วยให้คนอื่นผิดหวังได้ :)


6

ฉันได้รับข้อความแสดงข้อผิดพลาดเดียวกัน แต่ในสถานการณ์ของฉันฉันพยายามอัพเดตเอนทิตีที่ได้รับจากความสัมพันธ์แบบกลุ่มต่อกลุ่มโดยใช้ PJT (Pure Join Table)

จากการอ่านโพสต์อื่นฉันคิดว่าฉันสามารถแก้ไขได้โดยการเพิ่มฟิลด์ PK เพิ่มเติมลงในตารางการเข้าร่วม ... อย่างไรก็ตามถ้าคุณเพิ่มคอลัมน์ PK ลงในตารางการเข้าร่วมมันจะไม่ใช่ PJT อีกต่อไปและคุณจะสูญเสียข้อมูลทั้งหมด ข้อดีของเฟรมเวิร์กเอนทิตีเช่นการจับคู่ความสัมพันธ์อัตโนมัติระหว่างเอนทิตี

ดังนั้นทางออกในกรณีของฉันคือการเปลี่ยนตารางการเข้าร่วมในฐานข้อมูลเพื่อสร้าง PK ที่มีทั้งคอลัมน์ ID ต่างประเทศ


นี่เป็นวิธีที่การสร้าง EDMX ทำงานได้เสมอหรือไม่ ฉันคุ้นเคยกับการทำงานกับ Code First ซึ่งไม่จำเป็นต้องมี PK บนโต๊ะรวมที่บริสุทธิ์
Michael Hornfeck

4

อาจเกิดข้อผิดพลาดหากตารางของคุณไม่มีคีย์หลักในกรณีนี้ตารางคือ "อ่านอย่างเดียว" และคำสั่ง db.SaveChanges () จะทำให้เกิดข้อผิดพลาดเสมอ


4

ตั้งค่าคีย์หลักจากนั้นบันทึกตารางและรีเฟรชจากนั้นไปที่ Model.edmx ลบตารางและรับอีกครั้ง


3

ดังนั้นมันจริงเพียงแค่เพิ่มคีย์หลัก

หมายเหตุ: ตรวจสอบให้แน่ใจว่าเมื่อคุณอัพเดตไดอะแกรม EF ของคุณจากฐานข้อมูลที่คุณกำลังชี้ไปยังฐานข้อมูลที่ถูกต้องในกรณีของฉันสตริงการเชื่อมต่อถูกชี้ไปยังฐานข้อมูลท้องถิ่นแทนที่จะเป็น Dev Dev ที่ทันสมัยเด็กนักเรียน เกิดข้อผิดพลาดที่ฉันรู้ แต่ฉันต้องการโพสต์สิ่งนี้เพราะมันน่าหงุดหงิดมากถ้าคุณมั่นใจว่าคุณได้เพิ่มคีย์หลักและคุณยังคงได้รับข้อผิดพลาดเดียวกัน


2

ฉันมีปัญหาเดียวกัน ตามที่หัวข้อนี้กล่าวว่าตารางของฉันไม่มี PK ดังนั้นฉันจึงตั้งค่า PK และเรียกใช้รหัส แต่น่าเสียดายที่ข้อผิดพลาดมาอีกครั้ง สิ่งที่ฉันทำต่อไปคือลบการเชื่อมต่อฐานข้อมูล (ลบไฟล์. edmx ในโฟลเดอร์ Model ของ Solution Explorer) และสร้างใหม่ เกิดข้อผิดพลาดหลังจากนั้น ขอบคุณทุกคนที่แบ่งปันประสบการณ์ของคุณ ช่วยประหยัดเวลาได้มาก


1

ฉันได้รับปัญหานี้เพราะฉันสร้าง EDMX ของฉันจากฐานข้อมูลที่มีอยู่ (ออกแบบโดยคนอื่นและฉันใช้คำว่า 'ออกแบบ' ที่นี่อย่างหลวม ๆ )

ปรากฎว่าโต๊ะไม่มีกุญแจเลย EF กำลังสร้างแบบจำลองที่มีหลายปุ่มหลายปุ่ม ฉันต้องไปเพิ่มคีย์หลักลงในตาราง db ใน SQL แล้วอัปเดตโมเดลของฉันใน 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

เปิดไฟล์. edmx ของคุณในตัวแก้ไข XML จากนั้นลบแท็กออกจาก Tag และเปลี่ยนที่เก็บ: 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)

ตารางนักเรียนและหลักสูตรมีรหัสหลักและรหัสตามลำดับในขณะที่ตารางนักเรียนหลักสูตรมีสองคีย์ต่างประเทศที่แมปกับตารางนักเรียนและหลักสูตร

เหตุผลสกีมานั้นถูกต้อง แต่ฉันทำผิดพลาดในฐานข้อมูลเพราะทุกตารางควรมีคีย์หลัก

คำจำกัดความ SQL ของฉันสำหรับStudent-Courseคือ:

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

คุณพูดถูก แต่บางคนเพิ่มรหัสคีย์หลักพิเศษในตารางที่สามซึ่งไม่ใช่วิธีที่ดี
Summar Raja

ในขณะที่คำตอบอื่น ๆ ก็บอกว่า
เกอร์ทอาร์โนลด์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.