سؤال

أنا باستخدام إطار الكيان 4.3.1 رمز أولا وأنا بحاجة إلى تقسيم كيان بين جدولين.تحتوي الجداول على مفتاح أساسي مشترك ، وهو من 1 إلى 1 ، ولكن لا يتم تسمية الأعمدة بنفس الاسم في كل جدول.

لا أتحكم في تخطيط البيانات ، ولا يمكنني طلب أي تغييرات.

على سبيل المثال ، يمكن أن تكون جداول سكل

SQL data tables

وهذا سيكون كياني...

public class MyEntity
{
    public int Id {get; set;}
    public string Name {get;set}
    public string FromAnotherTable {get;set;}
}

وهنا هو رسم الخرائط لدي.

public class MyEntityMapping : EntityTypeConfiguration<MyEntity>
{
    public MyEntityMapping()
    {
        this.Property(e => e.Id).HasColumnName("ThePrimaryKeyId");
        this.Property(e => e.Name).HasColumnName("MyDatabaseName");
        this.Property(e => e.FromAnothertable).HasColumnName("AnotherTableColumn");
        this.Map(m =>
            {
                m.Properties(e =>
                     {
                         e.Id,
                         e.Name
                     });
                m.ToTable("MainTable");
            });
        this.Map(m =>
            {
                m.Properties(e =>
                     {
                         e.Id,
                         e.FromAnotherTable
                     });
                m.ToTable("ExtendedTable");
            });
}

نظرا لأن المفتاح المشترك بينهما له اسم عمود مختلف ، فأنا لست متأكدا من كيفية تعيينه.سيتم تجميع هذا التعيين ، ولكن فشل في وقت التشغيل لأن إف تنبعث سكل تبحث عن العمود "ثيبريماريكييد" على الجدول "إكستنددتابل" ، الذي لا وجود له.

تحرير لتوضيح ، ما قمت بتعريفه أعلاه يمكن (ولا) العمل إذا كان بيكاي على" إكستنددتابل " يتبع اصطلاحات التسمية.لكنه لا ولا يمكنني تغيير المخطط.

في الأساس ، ما أحتاج إف لتنبعث هو بيان سكل مثل

SELECT
    [e1].*,   /*yes, wildcards are bad. doing it here for brevity*/
    [e2].*
FROM [MainTable] AS [e1]
INNER JOIN [ExtendedTable] AS [e2]  /*Could be left join, don't care. */
    ON  [e1].[ThePrimaryKeyId] = [e2].[NotTheSameName]

لكن الشيء الوحيد الذي يبدو أنه يريد أن ينبعث منه هو

 SELECT
        [e1].*,
        [e2].*
    FROM [MainTable] AS [e1]
    INNER JOIN [ExtendedTable] AS [e2]
        ON  [e1].[ThePrimaryKeyId] = [e2].[ThePrimaryKeyId] /* this column doesn't exist */

تحرير حاولت نهج 1 إلى 1 مرة أخرى في اقتراح نسغاغا.لم ينجح الأمر ، لكن ها هي النتائج.الكيانات

public class MyEntity
{
    public int Id { get; set; }
    public int Name { get; set; }
    public virtual ExtEntity ExtendedProperties { get; set; }
}
public class ExtEntity
{
    public int Id { get; set; }
    public string AnotherTableColumn { get; set; }
    public virtual MyEntity MainEntry { get; set; }
}

وهنا الطبقات رسم الخرائط

public class MyEntityMapping : EntityTypeConfiguration<MyEntity>
{
    public MyEntityMapping()
    {
        this.Property(e => e.Id).HasColumnName("ThePrimaryKeyId");
        this.Property(e => e.Name).HasColumnName("MyDatabaseName");
        this.ToTable("MainTable");
        this.HasKey(e => e.Id);
        this.HasRequired(e => e.ExtendedProperties).WithRequiredPrincipal(f => f.MainEntry);
    }
}

public class ExtEntityMapping : EntityTypeConfiguration<ExtEntity>
{
    public ExtEntityMapping()
    {
        this.Property(e => e.Id).HasColumnName("NotTheSameName");
        this.Property(e => e.AnotherTableColumn).HasColumnName("AnotherTableColumn");
        this.ToTable("ExtendedTable");
        this.HasKey(e => e.Id);
        this.HasRequired(e => e.MainEntry).WithRequiredDependent(f => f.ExtendedProperties);
    }
}

هذا الإعداد يحصل على الرسالة

"Column or attribute 'MyEntity_ThePrimaryKeyId' is not defined in 'ExtendedTable'"

تغيير خط الخريطة النهائي إلى

this.HasRequired(e => e.MainEntry).WithRequiredDependent(f => f.ExtendedProperties).Map(m => M.MapKey("NotTheSameName"));

إرجاع هذه الرسالة

"Each property name in a type must be unique. property name 'NotTheSameName' was already defined."

تغيير المفتاح المعين لاستخدام العمود من الجدول الأصل, MapKey("ThePrimaryKeyId").إرجاع هذه الرسالة

"Column or attribute 'ThePrimaryKeyId' is not defined in 'ExtendedTable'"

إزالة Id الملكية من ExtEntity يلقي الفصل خطأ لأن الكيان لا يحتوي على مفتاح محدد.

هل كانت مفيدة؟

المحلول

لا يمكنني العثور على أي شيء ينص على وجه التحديد على أن اسم العمود يجب أن يكون هو نفسه في كلا الجدولين;ولكن لا يمكنني العثور على أي شيء يقول أنه لا ، أو يشرح كيف يمكنك تعيين هذا السيناريو.كل مثال يمكنني العثور عليه يحتوي على المفتاح الذي يحمل نفس الاسم في كلا الجدولين.يبدو لي مثل هذا هو ثقب في تصميم دبكونتيكست.

نصائح أخرى

لقد كنت أعمل على هذه المشكلة بالذات لبضعة أيام، ما فعلته أخيرا هو تعيين اسم عمود حقل المعرف داخل سياق جزء رسم الخرائط.بهذه الطريقة يمكنك إعطاء المعرف (أو المفتاح الخارجي المعتمد على المعرف) اسما مختلفا عن معرف الجدول الرئيسي.

this.Map(m =>
    {
        m.Property(p => p.Id).HasColumnName("NotTheSameName");
        m.Properties(e =>
             {
                 e.Id,
                 e.FromAnotherTable
             });
        m.ToTable("ExtendedTable");
    });

إذا قمت بتشغيل وتصحيح هذا ، سوف تجد أنه سوف تعطيك شيئا مثل ما تريد:

[e1].[ThePrimaryKeyId] = [e2].[NotTheSameName]

نقل هاسكولومننام إلى داخل التعيين:

this.Property(e => e.FromAnothertable).HasColumnName("AnotherTableColumn");
this.Map(m =>
    {
        m.Properties(e => new
             {
                 e.Id,
                 e.Name
             });
             m.Property(e => e.Id).HasColumnName("ThePrimaryKeyId");
             m.Property(e => e.Name).HasColumnName("MyDatabaseName");

           m.Property(e => e.Id).HasColumnName("ThePrimaryKeyId");
        m.ToTable("MainTable");
    });
this.Map(m =>
    {
        m.Properties(e => new
             {
                 e.Id,
                 e.FromAnotherTable
             });
        m.ToTable("ExtendedTable");
    });
}

لا يوجد استوديو مرئي هنا ، ولكن جرب هذا باستخدام نهج 1 إلى 1:

هذا.(ه = > ه. خصائص موسعة).هاسكونسترينت ((ه ، م) => e.Id == m.Id);

تحديث:
فيما يلي بعض الروابط التي قد تساعد (تعذر العثور على رابط مرجعي حقيقي)

كيفية إعلان علاقة واحدة إلى واحدة باستخدام رمز إطار الكيان 4 أولا (بوكو)
إطار الكيان 4 كتب 4 كود أولا:كيفية العمل مع أسماء المفاتيح الأولية والأجنبية غير التقليدية

وفقط لتوفير (كما وعدت) 1 إلى 1 (كيانين ، جدولين) رسم الخرائط ، لما يستحق.
هنا هو ما يعمل بالنسبة لي ، وينبغي في قضيتك...

public class MainTable
{
    public int ThePrimaryKeyId { get; set; }
    public string Name { get; set; }
}
public class ExtendedTable
{
    public int NotTheSameNameID { get; set; }
    public string AnotherTableColumn { get; set; }
    public MainTable MainEntry { get; set; }
}
public class MainDbContext : DbContext
{
    public DbSet<MainTable> MainEntries { get; set; }
    public DbSet<ExtendedTable> ExtendedEntries { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MainTable>()
            .HasKey(x => new { x.ThePrimaryKeyId });

        modelBuilder.Entity<ExtendedTable>()
            .HasKey(x => new { x.NotTheSameNameID });

        // Extended To Main 1 on 1
        modelBuilder.Entity<ExtendedTable>()
            .HasRequired(i => i.MainEntry)
            .WithRequiredDependent();
    }
}

...ورمز اختبار شيء من هذا القبيل...

using (var db = new UserDbContext())
{
    foreach (var userid in Enumerable.Range(1, 100))
    {
        var main = new MainTable { Name = "Main" + userid };
        db.MainEntries.Add(main);

        var extended = new ExtendedTable { AnotherTableColumn = "Extended" + userid, MainEntry = main };
        db.ExtendedEntries.Add(extended);
    }
    int recordsAffected = db.SaveChanges();
    foreach (var main in db.MainEntries)
        Console.WriteLine("{0}, {1}", main.Name, main.ThePrimaryKeyId);
    foreach (var extended in db.ExtendedEntries)
        Console.WriteLine("{0}, {1}, {2}, {3}", extended.AnotherTableColumn, extended.NotTheSameNameID, extended.MainEntry.Name, extended.MainEntry.ThePrimaryKeyId);
}

أن يخلق البرنامج النصي سكل التالية والجداول...

CREATE TABLE [MainTables] (
    [ThePrimaryKeyId] [int] NOT NULL IDENTITY,
    [Name] [nvarchar](4000),
    CONSTRAINT [PK_MainTables] PRIMARY KEY ([ThePrimaryKeyId])
)
CREATE TABLE [ExtendedTables] (
    [NotTheSameNameID] [int] NOT NULL,
    [AnotherTableColumn] [nvarchar](4000),
    CONSTRAINT [PK_ExtendedTables] PRIMARY KEY ([NotTheSameNameID])
)
CREATE INDEX [IX_NotTheSameNameID] ON [ExtendedTables]([NotTheSameNameID])
ALTER TABLE [ExtendedTables] ADD CONSTRAINT [FK_ExtendedTables_MainTables_NotTheSameNameID] FOREIGN KEY ([NotTheSameNameID]) REFERENCES [MainTables] ([ThePrimaryKeyId])

وملاحظة ، وفقا لمناقشتنا أعلاه...
هذا ليس 'تقسيم' - ولكن
(أ) رمز المنظمة البحرية الدولية الأولى لا تسمح بأي شيء من هذا القبيل (حاولت ذلك أولا وأيضا تعديل الهجرات يدويا ولكن انها 'داخليا' كل استنادا إلى أسماء الأعمدة المتوقعة هي نفسها ويبدو أن هناك أي وسيلة من حوله ، لهذا الإصدار من إف على الأقل.
(ب) هيكل الجدول الحكمة - الجداول يمكن أن ننظر بالضبط ما تحتاجه (كما قلت من قبل اعتدت عليه لربط جداول عضوية أسبنيت الحالية (التي لم أتمكن من تغيير) في بلدي الجدول المستخدم الذي لديه معرف المستخدم الخاص يشير إلى خارج/أسبنيت الجدول والمعرف.
صحيح ، لا يمكنك جعله باستخدام واحد ج # فئة النموذج-ولكن الجانب ج # هو أكثر مرونة بكثير وإذا كنت تستطيع التحكم في ج # التي ينبغي أن تعطي نفس التأثير ، لرأيي على الأقل (كما هو الحال في الاختبار ، يمكنك الوصول إليه دائما من خلال الكيان الموسع ، سواء الموسعة والأعمدة الرئيسية وانهم دائما مطابقة 1 إلى 1 والبقاء 'في المزامنة'.
نأمل أن يساعد هذا بعض
ملاحظة:لم يكن لديك ما يدعو للقلق معرف فك الخ.- فقط قم دائما بالوصول إلى الإدخال الرئيسي وإضافته عبر المدخل الرئيسي ، وستكون المعرفات على ما يرام.

تحرير:
يمكنك أيضا القيام بما يلي ، للحصول على مظهر الاضطرار إلى التعامل مع فئة واحدة فقط (أي.نوع من الانقسام)

public class ExtendedTable
{
    public int NotTheSameNameID { get; set; }
    public string AnotherTableColumn { get; set; }

    public string Name { get { return MainEntry.Name; } set { MainEntry.Name = value; } }
    // public int MainID { get { return MainEntry.ThePrimaryKeyId; } set { MainEntry.ThePrimaryKeyId = value; } }
    internal MainTable MainEntry { get; set; }

    public ExtendedTable()
    {
        this.MainEntry = new MainTable();
    }
}

...واستخدامها مثل هذا...

var extended = new ExtendedTable { AnotherTableColumn = "Extended" + userid, Name = "Main" + userid };  

...كما يمكنك العودة إلى اتجاه فك عن طريق القيام WithRequiredPrincipal بدلا من الاعتماد.
(أيضا جميع المراجع يجب أن تكون ث / س 'الظاهري' إذا كنت قد المطلوبة واحد الى واحد)
(ويمكن إجراء مينتابل 'الداخلية' كما انها هنا ، لذلك انها غير مرئية من الخارج - لا يمكن أن تتداخل كما أن إف لا يسمح-يعامل مثل نوتمابد)
...حسنا ، هذا أفضل ما يمكنني فعله:)

يبدو أنه تم إصلاحه في إطار الكيان 6.انظر هذه المشكلة http://entityframework.codeplex.com/workitem/388

أود أن أقترح استخدام بعض التعليقات التوضيحية للبيانات مثل هذا:

MainTable
---------
MainTableId
DatabaseName

ExtendedTable
----------
NotTheSameName
AnotherColumn

public class MainTable
{
 [Key]
 public int MainTableId { get; set; }
 public string DatabaseName { get; set; }

 [InverseProperty("MainTable")]
 public virtual ExtendedTable ExtendedTable { get; set; }
}

public class ExtendedTable
{
 [Key]
 public int NotTheSameName { get; set; }

 public string AnotherColumn { get; set; }

 [ForeignKey("NotTheSameName")]
 public virtual MainTable MainTable { get; set; }
}

واجهت هذه المشكلة ، وتم حلها عن طريق إضافة سمة عمود لمطابقة اسمي العمودين. [Key] [Column("Id")] public int GroupId { get; set; }

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top