EntityType nie ma zdefiniowanego błędu klucza

145

Kontroler:

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);
        }

    }
}

Model DbContext:

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;
    }
}

Tabela bazy danych:

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

W global.asax.cs

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

Powyższy kod zawiera listę wszystkich klas, nad którymi pracuję. Po uruchomieniu mojej aplikacji pojawia się błąd:

„Podczas generowania modelu wykryto jeden lub więcej błędów walidacji” oraz „Typ jednostki nie ma zdefiniowanego klucza”.

Koder
źródło
3
Sprawdź plik repozytorium. Wszystkie rozwiązania na tej stronie są niesamowite, ale w moim przypadku zrobiłem wszystko dobrze, ale zapomniałem zadeklarować tabelę jako DbSet i dodać ją do modelbuilder.configurations.
Tosh
W moim przypadku wskazałem kod na inną bazę danych i brakowało tabeli z bazy danych
Kristina Lex

Odpowiedzi:

168

Klasę Model należy zmienić na:

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; }
    }
}
Koder
źródło
1
mój kod działał (bez [Key]), dopóki nie zmienię typów danych (zmieniłem je na unsigned) i działa tylko bajt. Czy jest powód, dla którego nie mogę używać unsignedwartości?
Mihai Bratulescu
5
Entity Framework nie obsługuje liczb całkowitych bez znaku msdn.microsoft.com/en-us/library/vstudio/ ...
user2316116
1
A jeśli używasz go jako modelu w MVC, nie zapomnij odbudować!
RoJaIt
1
Wiele różnych rzeczy może powodować ten błąd. W moim przypadku omyłkowo oznaczyłem moje pole „Id” jako „prywatne” zamiast „publiczne” (nawyk z języka Java / JPA). Poniższa odpowiedź Larry'ego Raymonda jest prawdopodobnie „najlepszą” odpowiedzią na to pytanie. Zawiera listę większości typowych scenariuszy za „EntityType nie ma zdefiniowanego klucza błędu”.
paulsm4
98
  1. Upewnij się, że publiczni członkowie klasy uczniów są zdefiniowani jako właściwości w / {get; set;}(twoje są zmiennymi publicznymi - częsty błąd).

  2. Umieść [Key]adnotację na wybranej nieruchomości.

Larry Raymond
źródło
To był mój problem. Dzięki. Implementowałem interfejs, który wymaga tylko gettera dla ID
Henry Ing-Simmons,
81

Może się tak zdarzyć z kilku powodów. Niektóre z nich znalazłem tutaj , inne odkryłem samodzielnie.

  • Jeśli właściwość ma inną nazwę niż Id, musisz dodać [Key]do niej atrybut.
  • Klucz musi być właściwością, a nie polem.
  • Klucz musi być public
  • Kluczowymi musi być typu CLS zgodności, co oznacza, niepodpisane rodzaje podoba uint, ulongitd. Nie są akceptowane.
  • Ten błąd może być również spowodowany błędami konfiguracji .
BlueRaja - Danny Pflughoeft
źródło
3
Odkryłem również, że właściwość klucza musi być do odczytu i zapisu. Otrzymałem błąd OP, gdy miałem getter i brak setera we właściwości ID.
JohnFx,
1
@JohnFx jest absolutnie poprawne. Resharper został usunięty private setz niektórych nieruchomości podczas czyszczenia. Wynik był taki, że „EntityType nie ma zdefiniowanego błędu klucza”. Dlatego uważaj na narzędzia czyszczące, które usuwają niezbędny kod.
jeremysawesome,
W moim przypadku użyłem niepowiązanej nazwy, aby wspomnieć o numerze identyfikacyjnym klasy. Zmiana tego, jak wspomniano w twoim rozwiązaniu, rozwiązała mój problem. Dziękuję :)
Angela Amarapala
W przypadku korzystania z nieruchomości jak ID, Id, ClassNameID, ClassNameIdnie musisz użyć[Key] attribute
Pranav Bilurkar
21

Wiem, że ten post jest spóźniony, ale to rozwiązanie pomogło mi:

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

dodane [Kolumna (Kolejność = 0)] po [Klucz] można dodać z przyrostem o 1:

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

itp...

danigitman
źródło
To załatwiło sprawę dla mnie. Miałem już [Klucz], ale dodanie zamówienia rozwiązało problem.
Jaitsujin
19

W moim przypadku podczas tworzenia „kontrolera MVC 5 z widokiem przy użyciu Entity Framework” pojawiał się błąd.

Po prostu musiałem skompilować projekt po utworzeniu klasy Model i nie musiałem używać adnotacji [Klucz].

ChrisS
źródło
2
Tak - „Następnie skompiluj projekt. Rusztowanie interfejsu API sieci Web używa odbicia w celu znalezienia klas modelu, więc potrzebuje skompilowanego zestawu. ' zaczerpnięte z tej strony
Adam,
Dokładnie. Działa tylko „budowanie” i żadna z poprzednich odpowiedzi nie działa! Próbowałem na wiele sposobów iw końcu go zbudowałem i zadziałało! Potem przyszedłem tutaj i znalazłem tę odpowiedź, która jest poprawna.
William Hou
świetny. to był mój przypadek, po kompilacji wszystko zostało rozwiązane
alhpe
Tak .... DZIĘKUJĘ ... Dziwne, że jest to problem w nowym zaktualizowanym VS2019: D
JanBorup
11

Użycie klawisza [key] nie zadziałało, ale użycie właściwości id to robi. Po prostu dodaję tę właściwość w mojej klasie.

public int id {get; set;}
William Bello
źródło
1
Musi być [Key], ale właściwość o nazwie „ id” również będzie działać.
Michael Blackburn
public int Id {get; zestaw; } lub [klucz] ^ public int Id1 {get; zestaw; }
lawa
6

Obiekt musi zawierać pole, które będzie używane jako pole Primary Key, jeśli masz pole o nazwie, Idbędzie to domyślnie klucz podstawowy obiektu, do którego będzie się łączyć Entity Framework.

W przeciwnym razie dodaj [Key]atrybut powyżej tego pola, którego chcesz użyć jako pola Primary Key, a także musisz dodać przestrzeń nazw System.ComponentModel.DataAnnotations:

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

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

Mayer Spitzer
źródło
Dzięki! Dodanie pakietu System.ComponentModel.Annotations Nuget do naszego projektu testów jednostkowych naprawiło ten błąd. Wywoływałem aktualizację DbMigrator i kończyło się to niepowodzeniem, mimo że projekt domeny z naszymi modelami i DbContext miał odwołanie Nuget. Oba projekty tego potrzebują.
pwhe23
4

Dodatkowo pamiętaj, nie zapomnij dodać publicznego słowa kluczowego w ten sposób

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

musisz użyć takiego słowa kluczowego Public

[Key] 
public int RoleId { get; set; } //correct method
Udara Kasun
źródło
2

Powodem, dla którego struktura EF monituje o brak klucza, jest to, że platforma EF wymaga klucza podstawowego w bazie danych. Aby deklaratywnie powiedzieć EF, która właściwość jest kluczem, należy dodać [Key]adnotację. Lub najszybciej dodaj IDwłaściwość. Następnie platforma EF IDdomyślnie przyjmie jako klucz podstawowy.

UtillYou
źródło
Co się stanie, jeśli baza danych ma więcej niż jedno pole z sufiksem ID? Podczas regeneracji tracę atrybut klucza.
Richard Griffiths
Jeśli generujesz kod z bazy danych, jedna z kolumn w tabeli powinna być kluczem podstawowym tabeli.
Michael Blackburn
Jeśli chodzi o „edycję” wygenerowanego kodu, prawie zawsze jest on generowany jako partialklasa. Możesz utworzyć drugi plik jako partialklasę o tej samej nazwie i ponownie dodać właściwość z [Key]atrybutem.
Michael Blackburn
1

Nie musisz cały czas używać atrybutu klucza. Upewnij się, że plik mapowania poprawnie zaadresował klucz

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

i nie zapomnij dodać mapowania w OnModelCreating repozytorium

modelBuilder.Configurations.Add(new PacketHistoryMap());
Bzdury
źródło
1

Dla mnie model był w porządku. To dlatego, że miałem 2 różne wersje frameworka jednostki. Jedna wersja dla projektu internetowego i inna dla wspólnego projektu zawierającego modele.

Musiałem tylko skonsolidować pakiety nuget .

wprowadź opis obrazu tutaj

Cieszyć się!

Daniel
źródło
Co rozumiesz przez „konsolidację pakietów NuGet”? Nigdy o tym nie słyszałem ...
Rob Washington
0

W porządku, ale w moim przypadku mam dwie takie klasy

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; }
}
        }
    }

Po usunięciu klasy wyższej działa to dobrze.

Debendra Dash
źródło