Laden...

Linq to SQL - Klasse kann nicht erstellt werden

Erstellt von MMCSharp vor einem Jahr Letzter Beitrag vor einem Jahr 1.010 Views
M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr
Linq to SQL - Klasse kann nicht erstellt werden

Hallo zusammen,
Ich habe einen seltsamen Fehler. Ich versuche mit Linq to SQL eine Datenbank-verbindung zu einer lokalen Microsoft SQL- Server- Datenbank herzustellen. Jedoch sobald ich eine Linq to SQL - Klasse erstellen will, behauptet er bei jeglicher Benennung, dass der Name nicht eindeutig ist. Hat jemand Abhilfe für diesen Fehler?

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Mit Rechtsklick auf das Projekt, hinzufügen, Neues Element und dann Linq to SQL-Klassen ( im Visual Studio )

4.942 Beiträge seit 2008
vor einem Jahr

OK, ich dachte erst, du hättest evtl. die "LINQ to SQL Tools" nicht installiert: Add Missing LINQ to SQL Classes in VS 2017 and 2019

Welche VS-Version hast du und welchen Projekttyp (.NET 5/6 oder .NET Framework)?

PS: LINQ to SQL wird eigentlich nicht mehr in aktuellen Projekten verwendet, sondern andere ORMs (wie z.B. Entity Framework, Dapper, LINQ to DB, ...).

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Ich nutze schon Visual Studio 2022 .
Zu Entity Framework kann ich kein gutes, einfach verständliches Toutorial finden, wie es komplett aufgesetzt wird. Von Linq to DB habe ich so noch nichts gehört.
Was ist denn das Gängigste?

16.842 Beiträge seit 2008
vor einem Jahr

Was ist denn das Gängigste?

Entit Framework, gefolgt von Dapper.

Die Docs enthält ein vollständiges 0-100 Beispiel. Direkt erster Treffer bei Google Suche nach "Entit Framework tutorial"
Tutorial: Get Started with Entity Framework 6 Code First using MVC 5
Des weiteren gibt es dutzende vollständige Tutorials auf YouTube, LinkedIn Learning....

Was Du als "gutes, einfach verständliches Toutorial" empfindest; keine Ahnung.
Aber natürlich braucht man ein C# / .NET / SQL Basiswissen - sonst wirds mit jedem DB Tooling schwer.
Das fällt auch leider nicht vom Baum. Man muss sich einfach damit beschäftigen.

Ansonsten bitte [Hinweis] Wie poste ich richtig? beachten und die genaue Fehlermeldung posten.
Sonst wirds schwer mit dem Helfen und dem Recherchieren nach der Fehlermeldung.

PS: auch bei Linq-to-SQL arbeitet man primär mit Code First. Man braucht kein Visual Studio Tooling um mit Linq to SQL zu arbeiten.
Die Visual Studio Extension unterstützt sowieso vieles nicht. Macht kaum sinn diese einzusetzen (steht auch gleich auf der ersten Seite der VS Tooling Docs zu Linq to SQL).

The O/R Designer is a simple object relational mapper because it supports only 1:1 mapping relationships. In other words, an entity class can have only a 1:1 mapping relationship with a database table or view. Complex mapping, such as mapping an entity class to a joined table, is not supported; use the Entity Framework for complex mapping. Additionally, the designer is a one-way code generator. LINQ to SQL O/R Designer overview - Visual Studio (Windows)

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Wieder einmal möchte ich mich bedanken! Es ist etwas schwierig sich durch diesen riesigen Tschungel an imformationen allein durchzuwursteln. Ich werde mich dann jetzt an EF halten... ( sofern mich das andere Problem nicht einhohlt)

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Das Problem liegt wohl an Visual Studio 2022 hier wurde das Thema schon einmal besprochen.
how-do-i-get-linq-to-sql-to-work-in-visual-studio-2022

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Ich habe jetzt Entity Framework mit Database- First in mein Programm implementiert. In diesem Fall erstellt EF die Models ja selbst. Nun würde ich gerne wissen, wie die Models gehandhabt werden, in Verbindung mit Repository - Pattern. Werden diese direkt ins Repository eingebunden? Da somit das Repository- Interface nicht entkoppelt ist... Oder sehe ich das falsch?

16.842 Beiträge seit 2008
vor einem Jahr

Sowohl das Repository, das dazugehörige Interface wie auch die Entitäten sind Teil der Datenbankschicht.
Was Du mit "nicht entkoppelt" meinst, ist mir nicht klar. Was willst Du (nicht) entkoppeln? Das Repository muss alle Datenbank Entitäten (oder auch Projektionen) kennen, sonst kann es nicht funktionieren.

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Haben die Models in der Datenschicht was mit den Models in der UI Schicht zu tun? Oder schmeiße ich das jetzt durcheinander? Ich dachte das Model wird nur einmal geschrieben und in allen Schichten verwendet...

Nur zu meinem Verständnis jetzt

ich habe jetzt den Datenzugriff auf den MS SQL-Server via Entity Framework
dann habe ich ein generisches IRepository erstellt
darauf habe ich ein generisches Repository erstellt, das von IRepository erbt

dessweiteren habe ich ein Modelspezifisches IRepository => IAddressesRrepository das dann von IRepository erbt mit der dazu gehörenden Entity( Table )
zu Letzt habe ich ein AddressRepository erstellt das von beiden erbt => hier setzte ich den Context

instanziert wird alles in einer UnitOfWork

Wenn ich jetzt die Datenbank incl. Zugriff ändere, dann muss alles bis auf das Generische Repository und IRepository neu geschrieben werden? Ich dachte es muss lediglich das Repository ausgetauscht werden, in dem der Context festgelegt wird.

16.842 Beiträge seit 2008
vor einem Jahr

Nein, Modelle existieren pro Schicht, weshalb sie auch unterschiedliche Bezeichner haben.
Im DAL heissen die Entitäten, in der Ui ViewModels.

dann habe ich ein generisches IRepository erstellt
darauf habe ich ein generisches Repository erstellt, das von IRepository erbt

Eine Klasse erbt ein Interface nicht, sie implementiert es.

Wenn ich jetzt die Datenbank incl. Zugriff ändere, dann muss alles bis auf das Generische Repository und IRepository neu geschrieben werden?

Nicht das Interface, sondern die spezifischen Implementierungen, weshalb Intefaces im Sinne der Software Architektur auch generisch benannt werden und die Klassen spezifisch.


public interface IOrderRepository
public class OrderMssqlRepository : IOrderRepository

Mit einer guten Repository Architektur sind in den spezifischen Klassen aber nur spezifische Methoden.
Alle CRUD-Dinge kann man aus einem generischen Basis-Repository erben (gibts viele Beispiele zu).

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Vom Aufbau musste ich im spezifischen Interface die Entity angeben..


public interface IAddressesRepository : IReposetory<tbl_addresses>{ }

was doch jetzt eine Bindung schafft, die ich eigentlich in dem Interface nicht möchte...

16.842 Beiträge seit 2008
vor einem Jahr

Das ist auch korrekt so.
Eine spezifische Implementierung ist ohne spezifische Entität nicht möglich.

Edit: ein Beispiel, auf dessen Basis auch dieses Forum hier umgesetzt ist, sieht man hier
AspNetCoreEnterprisePlatform/UserAccountsRepository.cs at main · BenjaminAbt/AspNetCoreEnterprisePlatform

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Aber dann ist das Interface jetzt auch an das Entity Framework in diesem Fall gebunden, weil der "tbl_addresses" ein Model vom Entity Framework ist. d.h. , wenn ich jetzt einen Zugriff (theoretisch) mit Linq to SQL realisieren möchte, müsste ich hier jeweils ein neues spezifisches Interface anfertigen und ein neues Model in das Interface einbinden?!

P.s. mein Code ähnelt diesem sehr, jedoch vererbe ich die Methoden aus dem Repository

generisches Repository Interface:


    public interface IReposetory<TEntity> where TEntity : class
    {
        //Find Objects
        TEntity Get(int id);
        IEnumerable<TEntity> GetAll();
        IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);

        //Add Objects
        void Add(TEntity entity);
        void AddRange(IEnumerable<TEntity> entities);
        
        //Remove Objects
        void Delete(TEntity entity);
        void DeleteRange(IEnumerable<TEntity> entities);
    }


generisches Repository:


public class Repository<TEntity> : IReposetory<TEntity> where TEntity : class
    {
        protected readonly DbContext Context;

        public Repository(DbContext context) => Context = context;

        //Add one
        public void Add(TEntity entity) => Context.Set<TEntity>().Add(entity);

        //Add Range
        public void AddRange(IEnumerable<TEntity> entities) => Context.Set<TEntity>().AddRange(entities);

        //Remove One
        public void Delete(TEntity entity) => Context.Set<TEntity>().Remove(entity);

        //Remove Row
        public void DeleteRange(IEnumerable<TEntity> entities) => Context.Set<TEntity>().RemoveRange(entities);

        //Find
        public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate) { return Context.Set<TEntity>().Where(predicate); }

        //Find by Id
        public TEntity Get(int id) { return Context.Set<TEntity>().Find(id); }

        //get all
        public IEnumerable<TEntity> GetAll() { return Context.Set<TEntity>().ToList(); }

    }

speziefisches Repository Interface:


public interface IAddressesRepository : IReposetory<tbl_addresses>{ }

speziefisches Repository:



public class AddressesRepository : Repository<tbl_addresses>, IAddressesRepository
    {
        public AddressesRepository(CDB_Entities context) : base(context) { }

        //Cast Repository-Context (Contect) to Applicaton-Context (Entity Framework Context)
        public CDB_Entities CDB_Entities => Context as CDB_Entities;
    }

16.842 Beiträge seit 2008
vor einem Jahr

Du hast halt die Variante für Faule genommen, wunderst Dich nun halt über generierten Code, der spezifisch ist, weil Du Database First verwendet hast -> falsches Vorgehensmodell.
So würde man das mit den Anforderungen, die Du hast (aka ich will "jeden Provider verwenden"), niemals angehen. Steht übrigens auch in den Docs.

Man implementiert eine Entität ohne Abhängigkeit an den Provider (Code First -> POCO):
AspNetCoreEnterprisePlatform/UserAccountEntity.cs at d7c8852475bdf9d40a89655ba774a87cde82b4b1 · BenjaminAbt/AspNetCoreEnterprisePlatform

Spezifische Dinge, wie zB das Tabellenmapping macht man mit Konfigurationen
AspNetCoreEnterprisePlatform/UserAccountEntityConfig.cs at d7c8852475bdf9d40a89655ba774a87cde82b4b1 · BenjaminAbt/AspNetCoreEnterprisePlatform

Repository Implementierungen sind immer spezifisch, sowohl Modelle wie auch der Kontext (deswegen auch das Wort spezifisch).
AspNetCoreEnterprisePlatform/UserAccountsRepository.cs at d7c8852475bdf9d40a89655ba774a87cde82b4b1 · BenjaminAbt/AspNetCoreEnterprisePlatform

Willst Du Code Generatoren verwenden, dann musst mit den Einschränkungen leben, die sie mitbringen.
PS: ich halte es aber für ein Fehlvorgehen Dinge mit einzuplanen, die unrealistisch oder zum aktuellen Zeitpunkt nicht planbar sind (aka ein zweiter Provider auf Basis von Linq to SQL).
Mit einem Vorgehen wie "ich plan alles ein, was jemals kommen könnte", wirst Du nie zum Ende kommen.

Edit, nachdem Du den Code hinzugefügt hast:

Fehler, die mir auffallen:

Schau Dir einfach mein Repo Code ab, deswegen hab ich ihn veröffentlicht.

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Na das war jetzt ein Tag Arbeit alles zu finden und das Gefundene einigermahßen zu verstehen und "funktionierend" umzusetzen. Dass das nicht perfekt ist war mir fast klar.. Ich war unentschlossen zwischen IEnumerable und IQueryable. In dem Toutorial wurde extra darauf hingewiesen auf IQeryable zu verzichten und IEnumerable zu wälen . Themen zu Asynchronen Repositorys habe ich auch gefunden, aber da bin ich noch nicht ganz durchgestiegen. Vor allem wie Fehler abgefangen werden. Ich schaue mir auf jeden Fall die verlinkten Sachen genau an. Vielen Dank für deine Hilfe!

16.842 Beiträge seit 2008
vor einem Jahr

IEnumerable macht kein Sinn in Betrachtung von Intermediate materialization (C#). Tutorial vielleicht bisschen alt, oder anderen Fokus?
Sinn machen: IAsyncEnumerable (Docs) für asynchrones Laden für großen Inhalten inkl. asynchronem Paging (siehe dazu Asynchronous Programming - EF Core), List (Docs)(oder IList) für materialisierte Resultate oder IQueryable (Docs), wenn ein unausgeführter Query weitergegeben werden soll (zB weil die Logik das Execute übernehmen soll).

IQueryable kann/muss man halt bewusst anwenden, weil man die Ausführung bzw. dessen Verantwortung des Queries verlagert.
Aber ein IEnumerable zurück geben wenn man eine List hat, macht in 99% der realen Alltagsfälle kein Sinn. IEnumerable ist halt die maximale Abstrahierung einer Collection, tiefer geht nicht. Aber wozu Abstrahierung, wenn der materialisierte Zustand bereits eingetreten ist.
Dann lieber KISS und durch die konkrete Typisierung bereits klar machen: "Hey, ich bin schon materialized!". Wenn man nur IEnumerable an der Schnittstelle sieht, weiß man das nicht.

Dass das nicht perfekt ist war mir fast klar..

Kein Ding, wir alle haben viele Fehler gemacht und daraus gelernt.
Gehört dazu.

Vor allem wie Fehler abgefangen werden.

Kommt drauf an welche Fehler, gibt ja viele.
Wenn es Dir um Kontext Exceptions geht, so gibt es eine gute Erweiterung für bessere Exceptions
GitHub - Giorgi/EntityFramework.Exceptions: Handle database errors easily when working with Entity Framework Core. Supports SQLServer, PostgreSQL, SQLite, Oracle and MySql

Exceptionhandling is in fast allen Fällen Teil der Logik.

16.842 Beiträge seit 2008
vor einem Jahr

IEnumerable macht kein Sinn in Betrachtung von
>
.

Ich hab dazu mal ein LinkedIn Post gemacht, warum das nicht gut ist: Take care of your lists..
Der Code und Benchmark dazu: SustainableCode/csharp/list-vs-ienumerable-enumerate at main · BenjaminAbt/SustainableCode