Ho provato a cercare SO per la risposta e sono incappato in problemi simili, ma non ho potuto t riesco a usarli per risolvere il mio problema, quindi prova a non contrassegnarlo come duplicato. Passiamo al vero affare:T deve essere un tipo non astratto con un costruttore pubblico senza parametri per utilizzarlo come parametro "TModel" nel tipo o metodo generico
Ho una libreria generica per standardizzare i primi modelli di database del framework di entità. Queste sono le classi generiche che ho creato:
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;
}
}
e una classe per il ViewModel con pre-impostare MVC attributi
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; }
}
Inoltre, ho creato una classe di servizio che intendo di utilizzare all'interno del controller per ottenere i dati:
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();
}
}
la biblioteca compila bene, lo uso all'interno del progetto strato di dati dentro la mia MVC App. Iniziate creando una nuova vista del modello:
public class RoleViewModel : GenericLookupViewModel
{
}
Quindi, consente di creare un servizio:
public class RoleService : GenericLookupModelDataService<tblkp_Role, RoleViewModel>
{
}
rendere la classe eredita Entity Framework dal modello astratto:
partial class tblkp_Role : GenericLookupModel
{
}
lasciare infine di crea il nostro 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();
}
}
Ci scusiamo per il wall-of-code, alcuni codici sono già stati rimossi per brevità. Durante la compilazione mi dà 3 errori:
UPDATE: disponibile Class tblk_Role generato automaticamente da EF (DB Primo approccio):
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: Erros in formato testo:
Errore 33 'DataLayer.Model.tblkp_Role' deve essere un tipo non astratta con un pubblico costruttore senza parametri al fine di utilizzarlo come parametro 'tModel' nel tipo generico o di un metodo 'MyLib.Model.GenericLookupModelDataService < tModel, TViewModel >' C: \ Progetti \ Sources \ MyLib \ bin \ Release \ MyLib.dll
Errore 32 il tipo 'DataLayer.Model.tblkp_Role' non può essere utilizzato come parametro di tipo 'tModel' nel tipo generico o metodo 'MyLib.Model.GenericLookupModelDataService < tModel, TViewModel >'. Lì non è la conversione di boxe da "DataLayer.Model.tblkp_Role" a "MyLib.Model.GenericLookupModel". c: \ Progetti \ Sources \ MyLib \ bin \ Release \ MyLib.dll
Uno dei tuoi errori dice che devi aggiungere un riferimento. L'hai fatto? – Maarten
Per spiegarlo: Nel controller si utilizza il 'RoleService', che eredita direttamente da' GenericLookupModelDataService '. Una conseguenza di questo disegno è che qualsiasi altra classe che utilizza il 'RoleService' (ad esempio il tuo' EmployeeController') deve anche avere una conoscenza diretta di tutto ciò che è direttamente esposto nell'albero ereditario. Pertanto, anche 'tblkp_Role' deve essere conosciuto dal controller. –
Maarten
Sì, l'ho fatto. Il riferimento bibliografico esiste in tutti e 3 i progetti nella mia soluzione. Sembra che il controller non abbia problemi a conoscere tblkp_Role –