Entity Framework - Geçersiz Sütun Adı '* _ID "


103

Bunu Code First ve Database First EF arasındaki bir soruna daralttım, ancak nasıl düzelteceğimi bilmiyorum. Elimden geldiğince net olmaya çalışacağım, ama dürüst olmak gerekirse buradaki anlayışın bir kısmını kendim de özlüyorum. Bu Entity Framework 4.4'tür

Entity Framework'ün kullanıldığı bir projeyi devraldım, ancak gerçek dosyaların çoğu geri dönmenin gerçek bir yolu olmadan silindi. EF'yi (Önce Veritabanı) yeniden ekledim ve projenin etrafında inşa edildiği bir T4 kurulumunu kopyaladım. Tüm veritabanı modellerinin kod sürümlerini ve bir DBContext kod dosyasını üretti.

Bağlantı dizem "normal" bir .NET bağlantı dizesi gibi görünüyorsa, geçersiz bir sütun adı olan "ProcessState_ID" olmadığı konusunda bir hata alıyorum. ProcessState_ID hiç kod tabanında değil, EDMX dosyasında ya da herhangi bir şeyde değil. Bu, sorgudaki bazı otomatik EF dönüşümü gibi görünüyor.

Bağlantı dizesini Entity Framework modeliyle eşleştirdiğimde iyi çalışıyor.

Şimdi önceki kodu Entity Framework ile eşleştirmeye çalışırken, "normal" .NET bağlantı dizesini korumak istiyorum.

Bu yüzden burada iki sorum var: 1. Normal bir bağlantı dizesinden koddaki bir EF bağlantı dizesine geçmenin iyi bir yolu nedir? 2. Burada geçersiz sütun adı hatasını durdurmak için görmediğim başka bir düzeltme var mı?


3
Bu, yalnızca erişimcili bir navigasyon özelliğiniz varsa da olur:public virtual Person Person { get; }
Şafak Gür

Lütfen bir cevabı işaretleyin
Mahkum SIFIR

Yanıtlar:


92

Herhangi bir İKoleksiyonunuz olup olmadığını kontrol edin.

Bulduğum şey, bir tabloya başvuran bir ICollection'a sahip olduğunuzda ve onun anlayabileceği bir sütun olmadığında, tablolar arasında bağlantı kurmaya çalışmanız için bir tane yarattığıdır. Bu özellikle ICollection ile oluyor ve onu anlamaya çalışırken beni "batty" yaptı.


44
Sadece bu cevapta net olmak gerekirse, çünkü durumum için en doğruydu (ama problemimi çözene kadar bunu bilmiyordum). Tabloyu alırken OtherTable_ID ile ilgili bir hatayla karşılaşırsanız, OtherTable modelinize gidin ve orada bir ICollection <Table> bulunmadığından emin olun. Bir ilişki tanımlanmadan, çerçeve otomatik olarak OtherTable için bir FK'ye sahip olmanız gerektiğini ve bu ekstra özellikleri oluşturulan SQL'de oluşturduğunuzu varsayar.
LUKE

15
EF 4 saatimi boşa harcadı
Nitin S

2
@NitinSawant Thats it? EF, tüm kopyaları ve eklenmemiş kayıtları ile beni günde 4 saat boşa harcıyor.
Jacob

@LUKE Yorumunuz beni kurtardı. Seni çok seviyorum :)
Arad

1
@LUKE ihtiyacımız olan EF kahramanı, hak ettiğimiz EF kahramanı değil. Seni seviyorum.
Matthew Young

65

Bu, diğer 2 yanıtı hemen anlamayanlar (benim gibi) için geç bir giriş.

Yani...

EF, EBEVEYN TABLOLARI ANAHTAR-REFERANS'tan BEKLENEN adı eşlemeye çalışıyor ... ve ... YABANCI ANAHTAR adı ÇOCUK TABLOSU ilişkisinde "değiştirilmiş veya kısaltılmış" olduğundan ... yukarıdaki mesajı alırsınız.

(bu düzeltme EF sürümleri arasında farklılık gösterebilir)

BENİM İÇİN DÜZELTME:
"ForeignKey" özniteliğini modele EKLİYORUZ

public partial class Tour
{
    public Guid Id { get; set; }

    public Guid CategoryId { get; set; }

    [Required]
    [StringLength(200)]
    public string Name { get; set; }

    [StringLength(500)]
    public string Description { get; set; }

    [StringLength(50)]
    public string ShortName { get; set; }

    [StringLength(500)]
    public string TourUrl { get; set; }

    [StringLength(500)]
    public string ThumbnailUrl { get; set; }

    public bool IsActive { get; set; }

    [Required]
    [StringLength(720)]
    public string UpdatedBy { get; set; }

    [ForeignKey("CategoryId")]
    public virtual TourCategory TourCategory { get; set; }
}

4
Bu benim için çalıştı. Bu cevabı bulduğum tek yer olduğu için +1.
Jerry Benson-Montgomery

@Jerry Temel anahtarı tanımladım. Ama yine de arar Category_Id. EF'nin farklı sürümleri için düzeltmelerden bahsettiniz değil mi? EF 6.0 kullanıyorum, yapabildiğim düzeltme nedir?
Ajay Aradhya

@ ajay-aradhya Aslında, EF'in farklı versiyonları hakkında yorum yapan, aslen cevap veren, tutuklu-sıfır olan kişiydi.
Jerry Benson-Montgomery

@ JerryBenson-Montgomery boş ver! çalıştırdım. Aramasına neden olan 'bire bir' eşlemeydi *_ID. Geri referans dahil olmak üzere iyi çalıştı.
Ajay Aradhya

1
Bunu, bir meta veri kısmi sınıfı ekleyerek de düzeltebilirsiniz, böylece yeniden oluşturduğunuzda bunu düzeltmek zorunda kalmazsınız. [MetadataType(typeof(MetaData))] public partial class Tour { public class MetaData { [ForeignKey(nameof(TourCategory))] public virtual TourCategory TourCategory { get; set; } } }
Carter Medlin

40

Kutsal inek - saatlerce denedikten sonra, sonunda bunu çözdüm.

İlk olarak EF6 veritabanı yapıyorum ve "bilinmeyen sütun kapsamı" hatasını merak ediyordum - bir nedenden dolayı tablo adı alt çizgi sütun adı oluşturuyor ve var olmayan bir sütun bulmaya çalışıyordu.

Benim durumumda, tablolarımdan birinde başka bir tablodaki aynı birincil anahtara iki yabancı anahtar referansı vardı - bunun gibi bir şey:

Animals            Owners
=======            ======
AnimalID (PK)      Pet1ID    <- FK to AnimalID
                   Pet2ID    <- also FK to AnimalID

EF bazı garip sütun gibi adını üreten edilmiş Owners_AnimalID1ve Owners_AnimalID2daha sonra kendisini kırmaya devam etti.

Buradaki püf noktası, bu kafa karıştırıcı yabancı anahtarların Fluent API kullanılarak EF ile kaydedilmesi gerektiğidir!

Ana veritabanı bağlamınızda, OnModelCreatingyöntemi geçersiz kılın ve varlık yapılandırmasını değiştirin. Tercihen, EntityConfigurationsınıfı genişleten ayrı bir dosyanız olacaktır , ancak bunu satır içi yapabilirsiniz.

Nasıl yaparsan yap, şuna benzer bir şey eklemen gerekecek:

public class OwnerConfiguration : EntityTypeConfiguration<Owner>
{
    public OwnerConfiguration()
    {
        HasRequired(x => x.Animals)
            .WithMany(x => x.Owners)  // Or, just .WithMany()
            .HasForeignKey(x => x.Pet1ID);
    }
}

Ve bununla, EF beklediğiniz gibi (belki) çalışmaya başlayacaktır. Boom.

Ayrıca, yukarıdakileri null yapılabilir bir sütunla kullanırsanız aynı hatayı alırsınız - .HasOptional()bunun yerine kullanın .HasRequired().


İşte beni kamburlaştıran bağlantı:

https://social.msdn.microsoft.com/Forums/en-US/862abdae-b63f-45f5-8a6c-0bdd6eeabfdb/getting-sqlexception-invalid-column-name-userid-from-ef4-codeonly?forum=adonetefx

Ardından Fluent API belgeleri, özellikle yabancı anahtar örnekleri konusunda yardımcı olur:

http://msdn.microsoft.com/en-us/data/jj591620.aspx

Yapılandırmaları burada açıklandığı gibi anahtarın diğer ucuna da yerleştirebilirsiniz:

http://www.entityframeworktutorial.net/code-first/configure-one-to-many-relationship-in-code-first.aspx .

Şu anda karşılaştığım bazı yeni sorunlar var, ama eksik olan büyük kavramsal boşluk buydu. Umarım yardımcı olur!


1
Çok teşekkürler .. Aynı sorunu yaşadım.
Sachin Parashar

Bu benim için de çalıştı, Harita dosyasına benzer kod satırları ekledi: builder.HasOne(item => item.LogicalShipment).WithMany(s => s.Items).HasForeignKey(item => item.LogicalShipmentId).IsRequired();
DaminiVyas

14

Varsayımlar:

  • Table
  • OtherTable
  • OtherTable_ID

Şimdi şu yollardan birini seçin:


A)

Kaldırmak ICollection<Table>

Geri OtherTable_IDalırken ilgili bazı hatalarınız varsa, modelinize Tablegidin OtherTableve içinde bir tane olmadığından emin olun ICollection<Table>. Bir ilişki tanımlanmadan, çerçeve otomatik olarak OtherTable için bir FK'ye sahip olmanız gerektiğini ve bu ekstra özellikleri oluşturulan SQL'de oluşturduğunuzu varsayar.

Bu cevabın tüm Kredisi @ LUKE'a aittir. Yukarıdaki cevap, @drewid cevabı altındaki yorumudur. Yorumunun çok temiz olduğunu düşünüyorum, sonra cevap olarak yeniden yazdım.


B)

  • ekle OtherTableIdiçinTable

ve

  • Define OtherTableIdiçinde Tablede veritabanı

1
Ne kadar parlak bir cevap!
Arad

Bu cevap gerçekten de gün geçtikçe kaydedildi. ve LUKE sayesinde yorumunu okudum. @Drewid cevap zincirinin sonunda yapmış olsa da, harikaydı ve bu durumla yüzleşen çoğu kişi için gerekli olan şeydi.
Div Tiwari

3

Benim durumumda, şu şekilde iki yabancı anahtardan oluşan bir birincil anahtarı yanlış tanımlıyordum:

HasKey(x => x.FooId);
HasKey(x => x.BarId);

HasRequired(x => x.Foo)
    .WithMany(y => y.Foos);
HasRequired(x => x.Bar);

Aldığım hata, "geçersiz sütun adı Bar_ID" idi.

Bileşik birincil anahtarın doğru şekilde belirtilmesi sorunu çözdü:

HasKey(x => new { x.FooId, x.BarId });

...

3

Benim için bu davranışın nedeni Fluent API ile tanımlı eşlemeyle ilgili bir sorundu. A türünün isteğe bağlı B türü nesnesi olduğu ve B türünün birçok A nesnesi olduğu 2 ilişkili türüm vardı.

public class A 
{
    …
    public int? BId {get; set;}
    public B NavigationToBProperty {get; set;}
}
public class B
{
    …
    public List<A> ListOfAProperty {get; set;}
}

Haritalamayı akıcı api ile şöyle tanımlamıştım:

A.HasOptional(p=> p.NavigationToBProperty).WithMany().HasForeignKey(key => key.BId);

Ancak sorun şu ki, B türünün navigasyon özelliği vardı List<A>, bu nedenleSQLException Invalid column name A_Id

Üretilen SQL'i VS Output-> Debug penceresine çıkarmak için Visual Studio Debug'ı EF DatabaseContext.Database.Log'a ekledim

db.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);

Oluşturulan SQL B tablosundan 2 ilişkiye sahipti -> biri doğru kimliğe sahip diğeri ise A_Id

Sorunla ilgili sorun, bu B.List<A>navigasyon özelliğini eşlemeye eklememiş olmamdı.

Benim durumumda doğru haritalama şu şekilde olmalıydı:

A.HasOptional(p=> p.NavigationToBProperty).WithMany(x => x.ListOfAProperty).HasForeignKey(key => key.BId);

2

Benim durumumda, bu sorunun nedeni taşınan bir veritabanında eksik bir FOREIGN KEY kısıtlamasıydı. Dolayısıyla, var olan sanal ICollection başarıyla yüklenmedi.


1

Bende de bu sorun vardı ve görünen o ki birkaç farklı neden var. Benim için, bir gezinti nesnesi içeren ana sınıfta yanlışlıkla int olarak tanımlanan bir id özelliğine sahipti. Veritabanındaki id alanı, C # 'da longint'e karşılık gelen bigint olarak tanımlandı. Bu bir derleme zamanı hatasına neden olmadı, ancak OP'nin aldığı gibi aynı çalışma zamanı hatasına neden oldu:

// Domain model parent object
public class WidgetConfig 
{
    public WidgetConfig(long id, int stateId, long? widgetId)
    {
        Id = id;
        StateId = stateId;
        WidgetId = widgetId;
    }

    private WidgetConfig()
    {
    }

    public long Id { get; set; }

    public int StateId { get; set; }

    // Ensure this type is correct
    public long? WidgetId { get; set; } 

    public virtual Widget Widget { get; set; }
}

// Domain model object
public class Widget
{
    public Widget(long id, string name, string description)
    {
        Id = id;
        Name = name;
        Description = description;
    }

    private Widget()
    {
    }

    public long Id { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }
}

// EF mapping
public class WidgetConfigMap : EntityTypeConfiguration<WidgetConfig>
{
    public WidgetConfigMap()
    {
        HasKey(x => x.Id);
        ToTable(nameof(WidgetConfig));
        Property(x => x.Id).HasColumnName(nameof(WidgetConfig.Id)).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
        Property(x => x.StateId).HasColumnName(nameof(WidgetConfig.StateId));
        Property(x => x.WidgetId).HasColumnName(nameof(WidgetConfig.WidgetId));
    }
}   

// Service
public class WidgetsService : ServiceBase, IWidgetsService
{
    private IWidgetsRepository _repository;

    public WidgetsService(IWidgetsRepository repository)
    {
        _repository = repository;
    }

    public List<WidgetConfig> ListWithDetails()
    {
        var list = _repository.ListWithDetails();

        return new WidgetConfigMapping().ConvertModelListToDtoList(list).ToList();
    }
}   

// Repository
public class WidgetsRepository: BaseRepository<WidgetConfig, long>, IWidgetsRepository
{
    public WidgetsRepository(Context context)
        : base(context, id => widget => widget.Id == id)
    {
    }

    public IEnumerable<WidgetConfig> ListWithDetails()
    {
        var widgets = Query
            .Include(x => x.State)
            .Include(x => x.Widget);

        return widgets;
    }
}

1

Benim için sorun, tablonun uygulamamda iki kez eşleştirilmesiydi - bir kez Code First aracılığıyla, bir kez Database First aracılığıyla.

İkisinden birini kaldırmak benim durumumdaki sorunu çözer.


1

Benim için bu, EF'in çoğullaşma sorunları nedeniyle oldu. "-Status" gibi bir şeyle biten tablolar için, EF bunun tekil "-Statu" olduğunu düşünür. Varlık ve DB tablo adını "-StatusTypes" olarak değiştirmek onu düzeltti.

Bu şekilde, her güncellendiğinde varlık modellerini yeniden adlandırmanıza gerek kalmaz.


0

Aynı tabloya birden fazla yabancı anahtar referansınız varsa, InverseProperty'yi kullanabilirsiniz.

Bunun gibi bir şey-

[InverseProperty("MyID1")]
public virtual ICollection<MyTable> set1 { get; set; }
[InverseProperty("MyID2")]
public virtual ICollection<MyTable> set2 { get; set; }

0

Benim için (Visual Studio 2017 ve Entity Framework 6.1.3 altındaki ilk veritabanı modeli kullanarak), Visual Studio ve Yeniden Oluşturma yeniden başlatıldıktan sonra sorun ortadan kalktı.


Sebebini açıklamadığınız için bu soruya kesin bir cevap gibi görünmüyor. Yorum olarak konulmalıdır.
Ibo

0

Benim durumumda, tohum yöntemi verilerim hala önceki bir geçişte bırakılan bir tablo sütununu çağırıyordu. Automapper kullanıyorsanız eşlemelerinizi iki kez kontrol edin.


0

Benim durumumda zaten bir veritabanım var (Veritabanı ilkleri). Buradaki tüm yorumlar sayesinde çözümümü buldum:

Tabloların ilişkiye sahip olması gerekir, ancak sütunların adlarının farklı olması ve ForeignKey özniteliğinin eklenmesi gerekir.

[ForeignKey ("PrestadorId")] genel sanal AwmPrestadoresServicios Colaboradores {get; Ayarlamak; }

Yani, PRE_ID PK'dir, ancak diğer tablodaki FK PRESTADOR_ID'dir, o zaman çalışır. Buradaki tüm yorumlar sayesinde çözümümü buldum. EF, gizemli yollarla çalışır.


0

Aynı tabloda bir navigasyon özelliği ile bu sorunu yaşıyorsanız, mülkümüzün adını değiştirmeniz gerekecektir.

Örneğin :

Table : PERSON
Id
AncestorId (with a foreign key which references Id named Parent) 

Sen değiştirmek gerekecek AncestorIdiçin PersonId.

Görünüşe göre EF, ParentIdAncestor adlı bir tablo bulamadığı için bir anahtar oluşturmaya çalışıyor ...

DÜZENLEME: Bu, önce Veritabanı için bir düzeltmedir!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.