EntityType'ın anahtar tanımlı hatası yok


147

Denetleyici:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication1.Models;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcApplication1.Controllers
{
    public class studentsController : Controller
    {
        //
        // GET: /students/

        public ActionResult details()
        {
            int id = 16;
            studentContext std = new studentContext();
           student first = std.details.Single(m => m.RollNo == id);
            return View(first);
        }

    }
}

DbContext Modeli:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;

namespace MvcApplication1.Models
{
    public class studentContext : DbContext
    {
        public DbSet<student> details { get; set; }
    }
}

Model:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations.Schema;

namespace MvcApplication1.Models
{
    [Table("studentdetails")]
    public class student
    {
        public int RollNo;
        public string Name;
        public string Stream;
        public string Div;
    }
}

Veritabanı tablosu:

CREATE TABLE [dbo].[studentdetails](
    [RollNo] [int] NULL,
    [Name] [nvarchar](50) NULL,
    [Stream] [nvarchar](50) NULL,
    [Div] [nvarchar](50) NULL
)  

Global.asax.cs içinde

Database.SetInitializer<MvcApplication1.Models.studentContext>(null);

Yukarıdaki kod, üzerinde çalıştığım tüm sınıfları listeler. Uygulamamı çalıştırdığımda şu hatayı alıyorum:

"Model oluşturma sırasında bir veya daha fazla doğrulama hatası algılandı" ve "Varlık türünün tanımlı anahtarı yok".


3
Depo dosyasını kontrol edin. Bu sayfadaki tüm çözümler harika ama benim durumumda her şeyi doğru yaptım ama tabloyu DbSet olarak ilan etmeyi ve modelbuilder.configurations'a eklemeyi unuttum.
Tosh

Benim durumumda, kodu başka bir veritabanına işaret ettim ve tablo
Kristina Lex

Yanıtlar:


173

Model sınıfı şu şekilde değiştirilmelidir:

using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;

namespace MvcApplication1.Models
{
    [Table("studentdetails")]
    public class student
    {
        [Key]
        public int RollNo { get; set; }

        public string Name { get; set; }

        public string Stream { get; set; }

        public string Div { get; set; }
    }
}

1
[Key]Kodum, veri türlerini değiştirene kadar (olmadan ) çalıştı unsignedve yalnızca bayt çalışıyor, unsigneddeğerleri kullanamamamın bir nedeni var mı?
Mihai Bratulescu

5
Entity Framework işaretsiz tamsayıları desteklemiyor msdn.microsoft.com/en-us/library/vstudio/…
user2316116

1
Ve MVC'de bir model olarak kullanıyorsanız, yeniden inşa etmeyi unutmayın!
RoJaIt

1
Pek çok farklı şey bu hataya neden olabilir. Benim durumumda, yanlışlıkla "kimlik" alanımı "genel" yerine "özel" olarak işaretledim (Java / JPA'dan bir alışkanlık). Larry Raymond'un aşağıdaki yanıtı , muhtemelen bu soruya verilen "en iyi" yanıttır . "EntityType'ın anahtar tanımlı hatası yok" arkasındaki yaygın senaryoların çoğunu listeler.
paulsm4

99
  1. Öğrenci sınıfın emin kamu üyeleri olarak tanımlanan emin olun özellikleri w / {get; set;}(sizin herkese açık olan değişkenler - yaygın bir hatadır).

  2. [Key]Seçtiğiniz mülkün üzerine bir açıklama yerleştirin.


Bu benim sorunumdu. Teşekkürler. Yalnızca kimlik için alıcı gerektiren bir arabirim uyguluyordum
Henry Ing-Simmons

83

Bunun olmasının birkaç nedeni vardır. Bunlardan bazılarını burada buldum , diğerlerini kendi başıma keşfettim.

  • Özelliğin adı dışında başka bir ad varsa, niteliği ona Ideklemeniz [Key]gerekir.
  • Anahtarın bir alan değil, bir mülk olması gerekir.
  • Anahtarın olması gerekiyor public
  • Anahtar ihtiyaçlar imzasız türleri gibi, yani bir CLS uyumlu tip olmak uint, ulongizin verilmez vb.
  • Bu hata, yapılandırma hatalarından da kaynaklanabilir .

3
Ayrıca anahtar özelliğin okuma-yazma olması gerektiğini de buldum. Bir alıcı varken ve ID özelliğinde ayarlayıcı olmadığında OP hatası aldım.
JohnFx

1
@JohnFx kesinlikle doğru. Yeniden paylaşım aracı private set, bir temizleme sırasında bazı özelliklerden kaldırıldı . Sonuç, "EntityType'ın anahtar tanımlı hatası yok" oldu. Bu nedenle, gerekli kodu kaldıran temizleme araçlarına dikkat edin.
jeremysawesome

Benim durumumda, sınıfın kimliğini belirtmek için ilgisiz bir isim kullandım. Bunu sizin çözümünüzde belirtildiği gibi değiştirmek sorunumu çözdü. Teşekkür ederim :)
Angela Amarapala

Eğer gibi herhangi bir özelliğini kullanırsanız ID, Id, ClassNameID, ClassNameIdkullanmak zorunda gerekmez[Key] attribute
PPB

22

Bu yazının geç olduğunu biliyorum ama bu çözüm bana yardımcı oldu:

    [Key]
    [Column(Order = 0)]
    public int RoleId { get; set; }

[Anahtar] 1 artırılarak eklenebildikten sonra [Sütun (Sıra = 0)] eklendi:

    [Key]
    [Column(Order = 1)]
    public int RoleIdName { get; set; }

vb...


Bu benim için hile yaptı. Zaten [Anahtar] vardı ama sipariş eklemek sorunu çözdü.
Jaitsujin

19

Benim durumumda, "Görünümlü MVC 5 Denetleyici, Entity Framework kullanarak" oluştururken hata alıyordum.

Model sınıfını oluşturduktan sonra projeyi oluşturmam gerekiyordu ve [Anahtar] ek açıklamasını kullanmam gerekmiyordu.


2
Evet - 'Sonra, projeyi inşa edin. Web API iskelesi, model sınıflarını bulmak için yansıma kullanır, bu nedenle derlenmiş derlemeye ihtiyacı vardır. ' Bu sayfadan
Adam

Kesinlikle. Yalnızca "inşa etmek" işe yarar ve önceki yanıtların hiçbiri işe yaramaz! Pek çok yol denedim ve sonunda onu yaptım ve işe yaradı! Sonra buraya geldim ve bu cevabı buldum, bu doğru cevap.
William Hou

harika. bu benim durumumdu,
derlendikten

Evet .... TEŞEKKÜRLER .... Garip, bu yeni güncellenmiş VS2019'da bir sorun: D
JanBorup

11

[Anahtar] kullanmak benim için işe yaramadı, ancak bir id özelliği kullanmak işe yarıyor. Bu özelliği sadece sınıfıma ekliyorum.

public int id {get; set;}

1
Olması gerekiyor [Key], ancak " id" adlı bir özellik de çalışacaktır.
Michael Blackburn

public int Id {get; Ayarlamak; } veya [anahtar] ^ public int Id1 {get; Ayarlamak; }
lav

6

Nesne Primary Key, adı verilen bir alanınız varsa, Idbu varsayılan olarak Entity Framework'ün bağlanacağı nesnenin birincil anahtarı olarak kullanılacak bir alan içermelidir .

Aksi takdirde, [Key]kullanmak istediğiniz alanın üstüne özelliği eklemeniz gerekir Primary Keyve ayrıca ad alanını da eklemeniz gerekir System.ComponentModel.DataAnnotations:

public class myClass
{
    public int Id { get; set; }
    [Key]
    public string Name { get; set; }
}

https://stackoverflow.com/a/51180941/7003760


Teşekkürler! System.ComponentModel.Annotations Nuget paketini Unit Tests projemize eklemek bu hatayı benim için düzeltti. DbMigrator Güncellemesini arıyordum ve modellerimiz ve DbContext ile Domain projemiz Nuget referansına sahip olmasına rağmen başarısız oldu. Her iki projenin de buna ihtiyacı var.
pwhe23

4

Ek olarak, bunun gibi genel anahtar kelime eklemeyi unutmayın

[Key] 
int RoleId { get; set; } //wrong method

Bunun gibi Genel anahtar kelime kullanmalısınız

[Key] 
public int RoleId { get; set; } //correct method

2

EF çerçevesinin 'anahtar yok' isteminin nedeni, EF çerçevesinin veritabanında birincil bir anahtara ihtiyaç duymasıdır. EF'ye anahtarın hangi özellik olduğunu bildirimli olarak söylemek için bir [Key]ek açıklama eklersiniz . Veya en hızlı yol, bir IDmülk ekleyin . Ardından, EF çerçevesi IDvarsayılan olarak birincil anahtar olarak alacaktır .


Veritabanının ID ile son eklenmiş birden fazla alanı varsa ne olur? Yenilenme sırasında Anahtar özelliğini kaybediyorum.
Richard Griffiths

Kodu DB'den oluşturuyorsanız, tablodaki sütunlardan biri tablonun birincil Anahtarı olmalıdır.
Michael Blackburn

Oluşturulan kodu "düzenleme" ile ilgili olarak, neredeyse her zaman bir partialsınıf olarak oluşturulur . partialAynı ada sahip bir sınıf olarak ikinci bir dosya oluşturabilir ve özelliği [Key]öznitelikle tekrar ekleyebilirsiniz .
Michael Blackburn

1

Her zaman anahtar niteliği kullanmak zorunda değilsiniz. Eşleme dosyasının anahtarı doğru şekilde ele aldığından emin olun

this.HasKey(t => t.Key);
this.ToTable("PacketHistory");
this.Property(p => p.Key)
            .HasColumnName("PacketHistorySK");

ve eşlemeyi Deponun OnModelCreating bölümüne eklemeyi unutmayın.

modelBuilder.Configurations.Add(new PacketHistoryMap());

1

Benim için model iyiydi. Bunun nedeni , varlık çerçevesinin 2 farklı sürümüne sahip olmamdı. Web projesi için bir sürüm ve modelleri içeren ortak proje için bir başka sürüm.

Sadece nuget paketlerini birleştirmem gerekiyordu .

görüntü açıklamasını buraya girin

Zevk almak!


"Nuget paketlerini birleştirmek" ile ne demek istiyorsun? Bunu hiç duymadım ....
Rob Washington

0

Tamam ama benim durumumda bunun gibi iki sınıfım var

namespace WebAPI.Model
{
   public class ProductsModel
{ 
        [Table("products")]
        public class Products
        {
            [Key]
            public int slno { get; set; }

            public int productId { get; set; }
            public string ProductName { get; set; }

            public int Price { get; set; }
}
        }
    }

Üst sınıfı sildikten sonra benim için iyi çalışıyor.


0

Kodumdaki bu belirli satırı çözerek bu sorunu da kendi projemde çözdüm. Aşağıdakileri ekledim.

[DatabaseGenerated(DatabaseGeneratedOption.None)]

Hatamı anladıktan sonra gittim ve değiştirdim

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

Bu ayrıca, veritabanına her yeni satır eklendiğinde "Id" adlı alanın değerinin artmasını sağlar.

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.