2016-03-03 2 views
6

Ich versuche, eine generische GetById(T id) Methode zu implementieren, die Typen abdeckt, die unterschiedliche ID-Typen haben können. In meinem Beispiel habe ich eine Entität, die eine ID vom Typ int und eine vom Typ string hat.Wie generische GetById() zu implementieren, wo ID von verschiedenen Typen sein kann

Allerdings halte ich erhalte eine Fehlermeldung, und ich habe keine Ahnung, warum:

Der Typ ‚int‘ muss einen Referenztyp sein, um es als Parameter ‚TId‘ zu verwenden in der generischen Art der Methode IEntity

Entity-Schnittstelle:

für meine Domain-Modelle Um gerecht, die IDs vom Typ int oder string haben.

public interface IEntity<TId> where TId : class 
{ 
    TId Id { get; set; } 
} 

Entity Implementationen:

public class EntityOne : IEntity<int> 
{ 
    public int Id { get; set; } 

    // Other model properties... 
} 

public class EntityTwo : IEntity<string> 
{ 
    public string Id { get; set; } 

    // Other model properties... 
} 

Generisches Repository-Schnittstelle:

public interface IRepository<TEntity, TId> where TEntity : class, IEntity<TId> 
{ 
    TEntity GetById(TId id); 
} 

Generisches Repository Implementierung:

public abstract class Repository<TEntity, TId> : IRepository<TEntity, TId> 
    where TEntity : class, IEntity<TId> 
    where TId : class 
{ 
    // Context setup... 

    public virtual TEntity GetById(TId id) 
    { 
     return context.Set<TEntity>().SingleOrDefault(x => x.Id == id); 
    } 
} 

Repository Implementationen:

public class EntityOneRepository : Repository<EntityOne, int> 
    { 
     // Initialise... 
    } 

    public class EntityTwoRepository : Repository<EntityTwo, string> 
    { 
     // Initialise... 
    } 
+6

Warum Sie beschränken 'TId' auf' CLASS' Typen? Das wird nicht mit 'int' funktionieren (die Fehlermeldung macht das ziemlich klar). 'class' bedeutet" Referenztyp "in generischen Constraints. –

Antwort

2

Sie sollten die Einschränkung auf TId von Ihrem Repository Klasse

public abstract class Repository<TEntity, TId> : IRepository<TEntity, TId> 
where TEntity : class, IEntity<TId> 
{ 
    public virtual TEntity GetById(TId id) 
    { 
     return context.Set<TEntity>().Find(id); 
    } 
} 
+0

Dieser Vorschlag löst den Referenztyp Fehler, aber ich bekomme jetzt einen 'Operator == kann nicht auf Operanden vom Typ TId und TId' Fehler beim Versuch, die Übereinstimmung durch ID – Tomuke

+0

ausgeführt wird, funktioniert es gut, wenn ich 'verwenden .Find (id) 'anstelle von' .SingleOrDefault (x => x.Id == id) '. Ich würde erwarten, dass es genau die gleiche Sache hinter dieser Methode tut, also nicht sicher, warum '.Find()' gültig ist. – Tomuke

+0

es funktioniert nicht für mich. zeigt Fehler –

1

Um Ihre Frage zu entfernen:
Ich versuche, eine generische zu implementieren GetById (T id) -Methode, die Typen berücksichtigt, die unterschiedliche ID-Typen haben können. In meinem Beispiel habe ich eine Entität, die eine ID vom Typ int und eine vom Typ string hat.

public virtual TEntity GetById<TId>(TId id) 
    { 
     return context.Set<TEntity>().SingleOrDefault(x => x.Id == id); 
    } 

Für allgemeine Parameter, stellt nur eine generische Methode wie oben

2
public interface IEntity<TId> where TId : class 
{ 
    TId Id { get; set; } 
} 

Die where TId : class Einschränkung jede Implementierung erfordert eine Id zu haben, die von dem Objekt berechnet, die für Werttypen wie int nicht wahr ist .

Das ist, was die Fehlermeldung Ihnen sagt: The type 'int' must be a reference type in order to use it as parameter 'TId' in the generic type of method IEntity

Entfernen Sie einfach die contraint von IEntity<TId>

Verwandte Themen