how - Cree una lista desplegable para MVC3 utilizando Entity Framework(modelo.edmx) & Razor Views && Inserte un registro de base de datos en varias tablas
mvc add entity framework (2)
Bueno, en realidad tendré que decir que David tiene razón con su solución, pero hay algunos temas que me molestan:
- Nunca debe enviar su modelo a la vista => Esto es correcto
- Si crea un
ViewModel
e incluye el Modelo como miembro enViewModel
, entonces efectivamente envió su modelo a View => esto es MALO - Usar diccionarios para enviar las opciones a la vista => este estilo no es bueno
Entonces, ¿cómo se puede crear un mejor acoplamiento?
Utilizaría una herramienta como AutoMapper
o ValueInjecter para mapear entre ViewModel
y Model. AutoMapper
parece tener la mejor sintaxis y sentido, pero la versión actual carece de un tema muy severo: no es capaz de realizar la asignación de ViewModel
a Model (en ciertas circunstancias, como flattening, etc., pero esto está fuera de tema) ) Por lo tanto, en este momento prefiero usar ValueInjecter
.
Entonces crea un ViewModel
con los campos que necesita en la vista. Agregue los elementos de Lista de selección que necesita como búsquedas. Y los agrega como SelectLists ya. Para que pueda consultar desde un origen habilitado LINQ, seleccione el campo ID y texto y almacénelo como una lista de selección: gana que no tiene que crear un nuevo tipo (diccionario) como búsqueda y acaba de mover la new SelectList
de la vista al controlador.
// StaffTypes is an IEnumerable<StaffType> from dbContext
// viewModel is the viewModel initialized to copy content of Model Employee
// viewModel.StaffTypes is of type SelectList
viewModel.StaffTypes =
new SelectList(
StaffTypes.OrderBy( item => item.Name )
"StaffTypeID",
"Type",
viewModel.StaffTypeID
);
En la vista solo tienes que llamar
@Html.DropDownListFor( model => mode.StaffTypeID, model.StaffTypes )
De vuelta en el elemento de publicación de su método en el controlador, debe tomar un parámetro del tipo de su ViewModel
. Luego verifica la validación. Si la validación falla, debe recordar rellenar viewModel.StaffTypes
SelectList, porque este elemento será nulo al ingresar a la función de publicación. Así que tiendo a tener esas cosas de población separadas en una función. Usted simplemente devuelve la return new View(viewModel)
si algo está mal. Los errores de validación encontrados por MVC3 se mostrarán automáticamente en la vista.
Si tiene su propio código de validación, puede agregar errores de validación especificando a qué campo pertenecen. Verifique la documentación en ModelState
para obtener información sobre eso.
Si viewModel
es válido, debe realizar el siguiente paso:
Si es una creación de un nuevo elemento, debe completar un modelo desde viewModel
(el más adecuado es ValueInjecter
). Luego puede agregarlo a la colección EF de ese tipo y confirmar cambios.
Si tiene una actualización, primero obtiene el elemento db actual en un modelo. Luego puede copiar los valores de viewModel
vuelta al modelo (de nuevo, usar ValueInjecter
hace que lo haga muy rápido). Después de eso puedes SaveChanges
y listo.
No dude en preguntar si algo no está claro.
Después de leer cientos de artículos aquí sobre cómo crear una lista DropDown en MVC 3 con Razor Views, no pude encontrar uno que se ajustara a mi caso.
Situación: en última instancia, intento crear una Vista para agregar un empleado a una base de datos.
Aquí hay una imagen del modelo .EDMX que estoy usando (las tablas que usará create ().):
Objetivos:
Crear un empleado (Tengo Create.cshtml (fuertemente tipado) hecho con una vista parcial para las casillas de verificación StaffNotify) {Estoy usando un @model por separado en la vista parcial de Notify desde Create View, no estoy seguro si eso es seguro ??? @model ShadowVenue.Models.Employee y @model ShadowVenue.Models.StaffNotify)
Cree un cuadro desplegable para StaffTypeId (que insertará el valor [StaffTypeId] de la Tabla "StaffType" (que tiene una relación de 1 a muchos), pero mostrará el valor de la cadena [Type] en el menú desplegable)
Cree un cuadro desplegable para GenderId (que insertará el valor [GenderId] de la Tabla "Géneros" (que tiene una relación de 1 a muchos), pero mostrará el valor de la cadena [Género] en el menú desplegable)
Insertar el registro en la base de datos (tengo las notificaciones del personal en una tabla separada con una relación de 1 a 1 en la clave principal StaffId)
Parece que tengo problemas con el código del Controlador para esto.
No estoy seguro de si debería crear un Procedimiento almacenado dentro del modelo de EDMX, o presentar alguna consulta o sintaxis de método, no estoy seguro de cuál es la mejor manera.
Esta es mi primera aplicación MVC3 grande que usa el modelo de Entity Framework.
(Si necesita conocer alguno de los Nombres de propiedades de navegación para ayudar con la solución, hágamelo saber y se los proporcionaré)
No pase modelos de db directamente a sus puntos de vista. Tienes la suerte de estar usando MVC, así que encapsula usando modelos de vista.
Cree una clase de modelo de vista como esta:
public class EmployeeAddViewModel
{
public Employee employee { get; set; }
public Dictionary<int, string> staffTypes { get; set; }
// really? a 1-to-many for genders
public Dictionary<int, string> genderTypes { get; set; }
public EmployeeAddViewModel() { }
public EmployeeAddViewModel(int id)
{
employee = someEntityContext.Employees
.Where(e => e.ID == id).SingleOrDefault();
// instantiate your dictionaries
foreach(var staffType in someEntityContext.StaffTypes)
{
staffTypes.Add(staffType.ID, staffType.Type);
}
// repeat similar loop for gender types
}
}
Controlador:
[HttpGet]
public ActionResult Add()
{
return View(new EmployeeAddViewModel());
}
[HttpPost]
public ActionResult Add(EmployeeAddViewModel vm)
{
if(ModelState.IsValid)
{
Employee.Add(vm.Employee);
return View("Index"); // or wherever you go after successful add
}
return View(vm);
}
Luego, finalmente en su vista (que puede usar Visual Studio para andamiarlo primero), cambie el tipo heredado a ShadowVenue.Models.EmployeeAddViewModel. Además, donde van las listas desplegables, use:
@Html.DropDownListFor(model => model.employee.staffTypeID,
new SelectList(model.staffTypes, "ID", "Type"))
y de manera similar para el menú desplegable de género
@Html.DropDownListFor(model => model.employee.genderID,
new SelectList(model.genderTypes, "ID", "Gender"))
Actualización por comentarios
Para el género, también podría hacer esto si puede estar sin los genderTypes en el modelo de vista sugerido anteriormente (aunque, pensándolo bien, tal vez genere este lado del servidor en el modelo de vista como IEnumerable). Entonces, en lugar de la new SelectList...
continuación, usaría su IEnumerable.
@Html.DropDownListFor(model => model.employee.genderID,
new SelectList(new SelectList()
{
new { ID = 1, Gender = "Male" },
new { ID = 2, Gender = "Female" }
}, "ID", "Gender"))
Finalmente, otra opción es una tabla de búsqueda. Básicamente, mantienes los pares clave-valor asociados con un tipo de búsqueda. Un ejemplo de un tipo puede ser el género, mientras que otro puede ser el estado, etc. Me gusta estructurar el mío de esta manera:
ID | LookupType | LookupKey | LookupValue | LookupDescription | Active
1 | Gender | 1 | Male | male gender | 1
2 | State | 50 | Hawaii | 50th state | 1
3 | Gender | 2 | Female | female gender | 1
4 | State | 49 | Alaska | 49th state | 1
5 | OrderType | 1 | Web | online order | 1
Me gusta utilizar estas tablas cuando un conjunto de datos no cambia muy a menudo, pero aún debe enumerarse de vez en cuando.
¡Espero que esto ayude!