T muss ein nicht abstrakter Typ mit einem öffentlichen parameterlosen Konstruktor, um es zu verwenden als parameter 'TModel' im generischen Typ oder Methode

Ich habe versucht, auf der Suche SO für die Antwort und stolperte über ähnliche Probleme, aber ich konnte das nicht gelingt, verwenden Sie für die Lösung meines Problems ist, also bitte versuchen Sie nicht, markieren Sie diese als Duplikat. Let ' s move on, um den real deal:

Habe ich eine generische Bibliothek für die Standardisierung entity framework-database first-Modelle.
Diese sind generische Klassen, die ich erstellt habe:

public abstract class GenericLookupModel : IActive, ICreated, IModified, IIdentity, IStringValue
{
    public bool is_active { get; set; }
    public string value { get; set; }
    public string description { get; set; }
    public DateTime created_on { get; set; }
    public string created_by { get; set; }
    public DateTime modified_on { get; set; }
    public string modified_by { get; set; }
    public int id {get;set;}

    public void SetCreated(string creator = "SYSTEM")
    {
        created_by = creator;
        created_on = DateTime.Now;
    }

    public void SetModified(string modifier = "SYSTEM")
    {
        modified_by = modifier;
        modified_on = DateTime.Now;
    }
}

Und eine Klasse für das ViewModel mit pre-set-MVC-Parametern

public abstract class GenericLookupViewModel
{
    [Key]
    public int ID { get; set; }

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

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

    [Required]
    public bool Active { get; set; }

    [StringLength(50)]
    [DisplayName("Record last modified by")]
    public string ModifiedBy { get; set; }

    [DisplayName("Record last modified Date")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime ModifiedOn { get; set; }

    [StringLength(50)]
    [DisplayName("Record created by")]
    public string CreatedBy { get; set; }

    [DisplayName("Record creation Date")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime CreatedOn { get; set; }
}

Außerdem habe ich eine service-Klasse, die ich beabsichtige zu verwenden, in der Steuerung für das abrufen von Daten:

public abstract class GenericLookupModelDataService<TModel, TViewModel> : object 
    where TModel : GenericLookupModel, new()
    where TViewModel : GenericLookupViewModel, new()
{
    private readonly DbContext _db;

    private DbContext entities
    {
        get { return _db; }
    }

    public GenericLookupModelDataService()
    {
        _db =
            new DbContext(
                System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnectionString"].ConnectionString);
    }

    public virtual IEnumerable<TViewModel> ReadAllActive()
    {
        return entities.Set<TModel>().Where(x => x.is_active).Select(product => new TViewModel
        {
            ID = product.id,
            Active = product.is_active,
            Description = product.description,
            Name = product.value,
            CreatedBy = product.created_by,
            CreatedOn = product.created_on,
            ModifiedBy = product.modified_by,
            ModifiedOn = product.modified_on
        });
    }

    public virtual IEnumerable<TViewModel> Read()
    {
        return entities.Set<TModel>().Select(product => new TViewModel
        {
            ID = product.id,
            Active = product.is_active,
            Description = product.description,
            Name = product.value,
            CreatedBy = product.created_by,
            CreatedOn = product.created_on,
            ModifiedBy = product.modified_by,
            ModifiedOn = product.modified_on
        });
    }

    public virtual void Create(TViewModel product, string username = "SYSTEM")
    {
        var entity = new TModel
        {
            is_active = product.Active,
            description = product.Description,
            value = product.Name,
        };

        entity.SetCreated();
        entity.SetModified();

        _db.Set<TModel>().Add(entity);
        _db.SaveChanges();
    }

    public virtual void Update(TViewModel product, string username = "SYSTEM")
    {
        var entity = new TModel
        {
            id = product.ID,
            is_active = product.Active,
            description = product.Description,
            value = product.Name
        };
        entity.SetModified();


        _db.Set<TModel>().Attach(entity);
        entities.Entry(entity).State = EntityState.Modified;
        entities.SaveChanges();
    }

    public virtual void Destroy(TViewModel product)
    {
        var entity = new TModel {id = product.ID};

        entities.Set<TModel>().Attach(entity);
        entities.Set<TModel>().Remove(entity);
        entities.SaveChanges();
    }

    public virtual TViewModel GetByID(int ID)
    {
        var item = entities.Set<TModel>().Find(ID);
        var result = new TViewModel
        {
            ID = item.id,
            Active = item.is_active,
            CreatedBy = item.created_by,
            CreatedOn = item.created_on,
            Description = item.description,
            ModifiedBy = item.modified_by,
            ModifiedOn = item.modified_on,
            Name = item.value
        };
        return result;
    }

    public void Dispose()
    {
        entities.Dispose();
    }

}

Der Bibliothek kompiliert in Ordnung, ich benutze es in der Daten-Ebene Projekt-in meinem MVC-App. Beginnen Sie, indem Sie eine neue Ansicht Modell:

public class RoleViewModel : GenericLookupViewModel
{


}

Dann können einen Dienst erstellen:

public class RoleService : GenericLookupModelDataService<tblkp_Role, RoleViewModel> 
{

}

Stellen Sie die Entity Framework-Klassen Erben von der abstrakten Modells:

partial class tblkp_Role : GenericLookupModel
{

}

Schließlich wollen wir unsere controller:

public class EmployeeController : Controller
{
    private RoleService roleService;

    public EmployeeController()
    {
        dataService = new EmployeeService();
        PopulateLookups();
    }

    private void PopulateLookups()
    {
        roleService = new RoleService();
        ViewData["roles"] = roleService.ReadAllActive();
    }

    public ActionResult Index()
    {
        return View();
    }

}

Sorry für die wall-of-code -, code ist bereits aus Gründen der Kürze entfernt.
Beim kompilieren gibt er mir 3 Fehler:
T muss ein nicht abstrakter Typ mit einem öffentlichen parameterlosen Konstruktor, um es zu verwenden als parameter 'TModel' im generischen Typ oder Methode

UPDATE: Vorausgesetzt tblk_Role Klasse automatisch generiert durch EF (DB-First-Ansatz):

using System;
using System.Collections.Generic;

public partial class tblkp_Role
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public tblkp_Role()
    {
        this.tbl_Employee = new HashSet<tbl_Employee>();
    }

    public int id { get; set; }
    public string value { get; set; }
    public string desciption { get; set; }
    public bool is_active { get; set; }
    public System.DateTime created_on { get; set; }
    public string created_by { get; set; }
    public System.DateTime modified_on { get; set; }
    public string modified_by { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<tbl_Employee> tbl_Employee { get; set; }
}

UPDATE 2: Fehler im nur-text-format:

Fehler 33 'DataLayer.Modell.tblkp_Role' must be a non-abstract Art
mit einem öffentlichen parameterlosen Konstruktor, um es zu verwenden als
parameter 'TModel' im generischen Typ oder Methode
'MyLib.Modell.GenericLookupModelDataService<TModel,TViewModel>' c:\Projects\Sources\MyLib\bin\Release\MyLib.dll

Fehler 32 Der Typ 'DataLayer.Modell.tblkp_Role' kann nicht als Typ
parameter 'TModel' im generischen Typ oder Methode
'MyLib.Modell.GenericLookupModelDataService<TModel,TViewModel>'. Es
ist keine boxing-Konvertierung von 'DataLayer.Modell.tblkp_Role' zu
'MyLib.Modell.GenericLookupModel'. c:\Projects\Sources\MyLib\bin\Release\MyLib.dll

  • Einer Ihrer Fehler sagt, müssen Sie einen Verweis hinzufügen. Haben Sie das getan?
  • Das zu erklären: In Ihrem controller, den Sie verwenden, die RoleService, die direkt erbt von GenericLookupModelDataService<tblkp_Role, RoleViewModel>. Eine Konsequenz dieser Konstruktion ist, dass jede andere Klasse verwendet die RoleService (zum Beispiel Ihre EmployeeController) muss auch eine direkte Kenntnis der alles direkt ausgesetzt in der vererbungsstruktur. So, auch tblkp_Role muss bekannt sein, durch Ihre controller.
  • Ja, habe ich. Library-Referenz existiert in allen 3 Projekten, in meiner Lösung. Scheint der controller nicht irgendwelche Probleme haben, zu wissen, tblkp_Role
  • Sie zeigen nur eine partielle definition der tblkp_Role. Ist es nicht Abstrakt? Hat es einen öffentlichen parameterlosen Konstruktor?
  • Ja, es ist nicht Abstrakt und hat einen öffentlichen parameterlosen Konstruktor, in der Tat. Es generierte Entity Framework-Database First Ansatz. Ich habe es in den code.
  • Bitte copy/paste Fehler als text anstatt als Bilder posten (das ist nicht sehr freundlich für Menschen mit kleinen Bildschirmen oder sehbehindert sind, etc.). Vielen Dank.
  • Aktualisiert die post mit, dass die kosmetische Korrektur. Es ist in UPDATE 2
  • Der Dritte Fehler, können Sie auf die benötigte Baugruppe ersten? Möglicherweise müssen Sie zum referenzieren der aktuellen EF-Paket auch.
  • Sind die partiellen Klassen definiert, die in verschiedenen Baugruppen?
  • partielle Klassen werden in der gleichen Versammlung: "Alle partiellen Typdefinitionen, die gedacht werden, um Teile des gleichen Typs definiert werden muss, in der gleichen assembly und dem gleichen Modul (.exe-oder .dll-Datei). Partielle Definitionen können sich über mehrere Module." - von MSDN.
  • Ich weiß, ich dachte, dass je nach den Referenzen, wenn nur eine partielle Klasse sichtbar ist, dann könnte es erklären, ein Zustand (sagen, wenn nur die EF-erzeugt ein sichtbar war, es würde brechen die Einschränkung auf den service). Nun ich glaube nicht, dass es sein würde, diesen Fehler obwohl, Jeppe ist wahrscheinlich Recht mit seiner Antwort -- etwas fehlen, ist die Frage, oder aber es ist etwas, das ziemlich überraschend ist.
  • ist es möglich, erstellen Sie eine Klasse, die Sie erweitert tblkp_Role und verwenden Sie diese neue Klasse statt?

InformationsquelleAutor Adrian K. | 2016-01-20
Schreibe einen Kommentar