คุณสมบัติที่ขึ้นต่อกันใน ReferentialConstraint ถูกแมปกับคอลัมน์ที่สร้างโดยร้านค้า


98

ฉันได้รับข้อผิดพลาดนี้เมื่อเขียนไปยังฐานข้อมูล:

คุณสมบัติที่ขึ้นต่อกันใน ReferentialConstraint ถูกแม็พกับคอลัมน์ที่สร้างโดยร้านค้า คอลัมน์: 'PaymentId'

public bool PayForItem(int terminalId, double paymentAmount, 
      eNums.MasterCategoryEnum  mastercategoryEnum, int CategoryId, int CategoryItemId)
    {

        using (var dbEntities = new DatabaseAccess.Schema.EntityModel())
        {
            int pinnumber = 0;
            long pinid = 1; //getPinId(terminalId,ref pinnumber) ;
            var payment = new DatabaseAccess.Schema.Payment();
            payment.CategoryId = CategoryId;
            payment.ItemCategoryId = CategoryItemId;
            payment.PaymentAmount = (decimal)paymentAmount;
            payment.TerminalId = terminalId;
            payment.PinId = pinid;

            payment.HSBCResponseCode = "";
            payment.DateActivated = DateTime.Now;
            payment.PaymentString = "Payment";
            payment.PromotionalOfferId = 1;
            payment.PaymentStatusId = (int)eNums.PaymentStatus.Paid;

            //payment.PaymentId = 1;

            dbEntities.AddToPayments(payment);
            dbEntities.SaveChanges();
        }
        return true;
    }

สคีมาคือ:

ป้อนคำอธิบายภาพที่นี่

คำตอบ:


181

เป็นไปได้ไหมว่าคุณกำหนดความสัมพันธ์ของคอลัมน์ที่ไม่ถูกต้องระหว่างตารางของคุณ คอลัมน์ที่แตกต่างกันและคอลัมน์หนึ่งถูกตั้งค่าเป็นตัวเลขอัตโนมัติ

มันเกิดขึ้นกับฉัน


55
ฉันทำคีย์ต่างประเทศของฉันผิดพลาดเป็นรหัสประจำตัว (เพิ่มขึ้นอัตโนมัติ) นี่คือข้อผิดพลาดที่ฉันได้รับ
jocull

3
ดู๊! ฉันได้ออกจากส่วนคีย์ภายนอกของความสัมพันธ์เป็นค่าเริ่มต้นที่กำหนดโดย SQL Server 2008 Management Studio ซึ่งเป็นฟิลด์คีย์หลักของตารางลูกไม่ใช่คอลัมน์ที่ฉันสร้างขึ้นเพื่อให้มีค่าคีย์ต่างประเทศ
robaker

12
หากคุณตรวจสอบข้อยกเว้นในหน้าต่าง Quick Watch (กล่าวคือ(e as System.Data.Entity.Infrastructure.DbUpdateException).Entries) คุณสามารถดูได้ว่าตารางใดมีคีย์หลักที่อ้างถึง
Cᴏʀʏ

17
จะดีไหมถ้าข้อความแสดงข้อผิดพลาดของ EF ระบุว่าปัญหาคืออะไรแทนที่จะพ่น gobbledy-gook?
AR

ฉันใช้แบบสอบถามนี้เพื่อดูความสัมพันธ์ทั้งหมดในมุมมองเดียวstackoverflow.com/questions/8094156/…
Dave

48

ข้อผิดพลาดนี้บอกว่าคุณกำลังใช้ความสัมพันธ์ที่ไม่รองรับหรือคุณมีข้อผิดพลาดในการทำแผนที่ รหัสของคุณส่วนใหญ่อาจไม่เกี่ยวข้องกับข้อผิดพลาด

ข้อผิดพลาดหมายความว่าคุณมีความสัมพันธ์บางอย่างระหว่างเอนทิตีที่คุณสมบัติของคีย์ต่างประเทศในเอนทิตีที่เกี่ยวข้องถูกกำหนดเป็นที่เก็บที่สร้างขึ้น เก็บคุณสมบัติที่สร้างขึ้นจะถูกกรอกในฐานข้อมูล EF ไม่สนับสนุนคุณสมบัติที่จัดเก็บเป็นคีย์ต่างประเทศ (เช่นเดียวกับคุณสมบัติที่คำนวณในคีย์หลัก)


2
ฉันสามารถเพิ่มแถวในเซิร์ฟเวอร์ sql ด้วยข้อมูลเดียวกัน เมื่อคุณพูดว่า Store Generated คุณสามารถยกตัวอย่างได้ไหม
Welsh King

1
EF ไม่ใช่ SQL Server มันมีข้อ จำกัด ในตัวเอง เพียงแค่ค้นหาตำแหน่งที่คุณใช้คุณสมบัติ FK ที่สร้างโดย DB ที่เรียกPaymentIDและจัดการกับมัน
Ladislav Mrnka

ตกลงเรามีตารางประวัติการชำระเงินที่มี PaymentId เป็นคีย์ต่างประเทศฉันต้องเพิ่มแถวในนั้นหรือไม่?
Welsh King

ไม่เกี่ยวกับการเพิ่มแถว แต่เกี่ยวกับนิยามของคอลัมน์ คุณตั้งคอลัมน์นั้นอย่างไร?
Ladislav Mrnka

เพียงคลิกโมเดลความสัมพันธ์ในสตูดิโอภาพและฉันได้รับชื่อ 'การชำระเงิน' ไม่สามารถใช้ในประเภท 'การชำระเงิน' ได้ ชื่อสมาชิกต้องไม่เหมือนกับประเภทการปิดล้อม ความคิดใด ๆ
Welsh King

8

ผมมีปัญหาเหมือนกัน. จากคำตอบที่ให้ไว้ที่นี่ฉันสามารถติดตามและแก้ไขได้ แต่ฉันมีปัญหาแปลก ๆ ที่อธิบายไว้ด้านล่างซึ่งอาจช่วยใครบางคนได้ในอนาคต

ในตารางที่ขึ้นกับของฉันคอลัมน์ Foreign Key ถูกตั้งค่าเป็น StoreGeneratedPattern = "Identity" ฉันต้องเปลี่ยนเป็น "ไม่มี" น่าเสียดายที่การทำภายในดีไซน์เนอร์ไม่ได้ผลเลย

ฉันดูใน XML (SSDL) ที่นักออกแบบสร้างขึ้นและคุณสมบัติเหล่านี้ยังคงอยู่ที่นั่นดังนั้นฉันจึงลบออกด้วยตนเอง ฉันต้องแก้ไขคอลัมน์บนฐานข้อมูลด้วย (ลบ Identity (1,1) จาก CREATE TABLE SQL)

หลังจากนั้นปัญหาก็หมดไป


ขอบคุณสำหรับเคล็ดลับนี้ การเปลี่ยนฟิลด์ในตัวออกแบบจาก Identity เป็น None เปลี่ยนสิ่งนี้ในที่เดียวใน EDMX แต่ไม่ใช่ที่อื่นดังนั้นฉันจึงยังคงได้รับข้อผิดพลาดจนกว่าฉันจะแก้ไขไฟล์ EDMX ด้วยตัวเอง น่าเสียดายที่ EntityFramework เกิดความบ้าคลั่งและพยายามแทรกเอนทิตีที่เกี่ยวข้องอีกครั้งในตารางอื่น ๆ แต่ก็ยังเป็นความช่วยเหลือในการข้ามข้อความแสดงข้อผิดพลาดนั้น
FTWinston

6

ฉันมีปัญหาเดียวกันและหลังจากที่มีการขุดในการออกแบบตารางในเซิร์ฟเวอร์ sql ฉันพบว่าฉันตั้งค่าคีย์หลักของตารางโดยไม่ถูกต้องเป็นคีย์ต่างประเทศ

ขั้นตอนการออกแบบตารางเซิร์ฟเวอร์ sql

ในภาพนี้คุณจะเห็นว่า JobID เป็นคีย์หลักของตาราง แต่ยังผิดคีย์ต่างประเทศด้วย


2

ปัญหาของฉันเกิดจากการกำหนดคีย์หลักซ้ำซ้อนในการกำหนดค่า

this
   .Property(p => p.Id)
   .HasColumnName(@"id")
   .IsRequired()
   .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity) // this is redundant when you want to configure a One-to-Zero-or-One relationship
   .HasColumnType("int");

ลบบรรทัดนี้

.HasDatabaseGeneratedOption (DatabaseGeneratedOption.Identity)


ตัวอย่างhttp://www.entityframeworktutorial.net/code-first/configure-one-to-one-relationship-in-code-first.aspx

นี่เพียงพอที่จะกำหนดความสัมพันธ์

// Configure Student & StudentAddress entity
modelBuilder.Entity<Student>()
            .HasOptional(s => s.Address) // Mark Address property optional in Student entity
            .WithRequired(ad => ad.Student); // mark Student property as required in StudentAddress entity. Cannot save StudentAddress without Student

1

ตรวจสอบความสัมพันธ์ระหว่างการชำระเงินกับตาราง / เอนทิตีอื่น ๆ อีกครั้ง รวมถึงสิ่งที่ไม่ควรมี PaymentId เพราะนั่นคือจุดที่ปัญหามักจะซ่อนอยู่

เมื่อสร้างคีย์ต่างประเทศใน SQL Server Management Studio คีย์หลักจะเป็นค่าเริ่มต้นและค่าเริ่มต้นนี้จะถูกเปลี่ยนกลับเมื่อตารางหลักมีการเปลี่ยนแปลงดังนั้นโปรดระมัดระวังในการเปลี่ยนค่าตามลำดับที่ถูกต้องในหน้าต่าง "ตารางและคอลัมน์"

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


1

หากคุณได้ตรวจสอบความสัมพันธ์ของคุณและมีความสุขดี

ลบตารางใน edmx แล้วอัปเดตจากฐานข้อมูล วิธีนี้จะช่วยให้คุณทำการอัปเดตด้วยตนเอง


ขอบคุณจริงๆสำหรับคำแนะนำฉันใช้เวลา 1 ชั่วโมงในการตรวจสอบฐานข้อมูลของฉัน แต่หลังจากลบออกแล้วอัปเดตทุกอย่างก็โอเค
TấnNguyên

1

สำหรับฉันมันเป็นคีย์ต่างประเทศที่วางผิดในตาราง แต่ถึงแม้จะแก้ไขตารางเพื่อแก้ไขแล้วก็ยังใช้งานไม่ได้ คุณต้องอัปเดตไฟล์ EDMX (และไม่เพียงพอที่จะ "รีเฟรช" ตารางจากโมเดลคุณต้องลบและเพิ่มตารางอีกครั้งในโมเดล)


1

นอกเหนือจากคำตอบที่ยอมรับแล้วหากคุณใช้ EF Reverse POCO generator หรือเครื่องมืออื่น ๆ ที่สร้าง POCO ของคุณตรวจสอบให้แน่ใจว่าคุณสร้างมันขึ้นมาใหม่ !


อย่าลืมเรียกใช้ Custom T4 Tool ของคุณอีกครั้ง (ถือ POCOs) หลังจากแก้ไขตัวสร้างโมเดล EF แรก DB ภายนอกของคุณ (ถือบริบท) ... เคย! XD (อาจจะบ้าไปแล้วก็ได้ -.- ')
Shockwaver

0

ในกรณีของฉันปัญหาเกิดจากการมีความสัมพันธ์ 1-1 แบบสองทาง:

class Foo{
[Key]
Id
[ForeignKey]
BarId
...
}
class Bar{
[Key]
Id
[ForeignKey]
FooId
...
}

ฉันต้องลบหนึ่งในสองคีย์ต่างประเทศ (ไม่จำเป็นต่อไป)


0

ในกรณีของฉันเป็นเพียงการที่ฉันไม่ได้ตั้งค่าสิทธิ์อย่างถูกต้องบนฐานข้อมูล ฉันได้อ่านเพียง set และ Entity framework ทำให้ฉันมีข้อผิดพลาด ReferentialConstraint ซึ่งทำให้ฉันผิดหวัง เพิ่มสิทธิ์การเขียนเพิ่มเติมและทุกอย่างก็ทำได้ดี


0

ในกรณีของฉันฉันมีคุณสมบัติที่สร้างฐานข้อมูลและคุณสมบัติการนำทาง ForeignKey ที่ตั้งค่าเพื่ออ้างอิงตารางที่เกี่ยวข้อง 1 ถึง 1

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

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

ดังนั้นเอนทิตีดั้งเดิมของฉันจึงมีลักษณะดังนี้:

public partial class MyEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid id{ get; set; }


    // Navigation
    [ForeignKey("id")]
    public PathEntity Path { get; set; }
}

ดังนั้นฉันจึงสร้างบริบทพิเศษที่สืบทอดมาซึ่งมีลักษณะดังนี้:

    private class _navPropInhibitingContext : EF.ApplicationDBContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<MyEntity>()
                .Ignore(e => e.Path);

        }
    }

จากนั้นเปลี่ยนรหัสที่สร้างเอนทิตีใหม่เพื่อให้ผู้ใช้ประเภทบริบทใหม่

    using (var specialContext = new _navPropInhibitingContext())
    {
        var dbModel = new MyEntity() 
        {
            ...
        };

        specialContext.MyEntity.Add(dbModel);
        await specialContext.SaveChangesAsync();
    }

หวังว่านี่จะช่วยใครสักคน


0

ในกรณีของฉันฟิลด์ Id ซึ่ง FK อยู่ใน Entity Framework เท่านั้น "StoreGeneratedPattern" propierty ถูกตั้งค่าเป็น "Itentity" แทน "None"

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