อัปเดต:ฉันเพิ่งได้รับการอัปเดตไม่กี่ครั้งเมื่อเร็ว ๆ นี้ดังนั้นฉันจึงคิดว่าฉันจะให้คนอื่นรู้ว่าคำแนะนำที่ฉันให้ไว้ด้านล่างไม่ใช่สิ่งที่ดีที่สุด ตั้งแต่แรกเริ่มที่ฉันเริ่มทำ 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 จากการเขียนนี้)
คลิกขวาที่ไฟล์. edmx ของคุณใน Solution Explorer เลือก "เปิดด้วย ... " จากนั้นเลือก "ตัวแก้ไข XML (ข้อความ)" เราจะแก้ไขโค้ดที่สร้างขึ้นอัตโนมัติด้วยมือที่นี่
ค้นหาบรรทัดดังนี้:
<EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" store:Schema="dbo" store:Name="table_nane">
ลบออกstore:Name="table_name"
จากจุดสิ้นสุด
เปลี่ยนstore:Schema="whatever"
เป็นSchema="whatever"
ดูด้านล่างบรรทัดนั้นและค้นหา<DefiningQuery>
แท็ก มันจะมีคำสั่งเลือก ol ขนาดใหญ่ในนั้น ลบแท็กและเนื้อหา
ตอนนี้สายของคุณควรมีลักษณะเช่นนี้:
<EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />
เรามีสิ่งอื่นที่จะเปลี่ยนแปลง ผ่านไฟล์ของคุณและค้นหาสิ่งนี้:
<EntityType Name="table_name">
ในบริเวณใกล้เคียงคุณอาจเห็นข้อความที่มีความคิดเห็นเตือนคุณว่าไม่ได้ระบุคีย์หลักดังนั้นจึงมีการสรุปคีย์และคำจำกัดความเป็นตาราง / มุมมองแบบอ่านอย่างเดียว คุณสามารถทิ้งไว้หรือลบทิ้ง ฉันลบมัน
ด้านล่างเป็น<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)
และด้วยคำเตือนนั้น ... ตอนนี้คุณน่าจะไปได้ดี!