2010-03-15 10 views
5

Me gustaría implementar MVC mientras uso LINQ (específicamente, LINQ-to-entities). La forma en que haría esto es hacer que el Controlador genere (o llame a algo que genere) el conjunto de resultados usando LINQ, luego regréselo a la Vista para mostrar los datos. El problema es, si lo hago:Forma simple de devolver tipos anónimos (para hacer posible MVC usando LINQ)

return (from o in myTable select o); 

Todos las columnas se leen de la base de datos, incluso los que (potencialmente decenas) que no quiero. Y - más importante - que no puede hacer algo como esto:

return (from o in myTable select new { o.column }); 

porque no hay manera de hacer con seguridad de tipos anónimos! Sé con certeza que no hay una forma agradable y limpia de hacerlo en 3.5 (this no está limpio ...), , pero ¿qué hay de 4.0? ¿Hay algo planeado, o incluso propuesto? Sin algo así como duck-typing-for-LINQ, o valores de retorno anónimos seguros de tipo (me parece que el compilador sin duda debería ser capaz de eso), parece ser casi imposible separar limpiamente el controlador de la vista.

+0

Cuando trabaje con un orm, debería acostumbrarse a la idea de que sql seleccione todas las columnas de una tabla. Si escribe consultas que seleccionan solo unas pocas, podría estar utilizando sql en primer lugar. Si tiene docenas de propiedades en sus objetos, ese es su problema. Tus objetos deberían ser más pequeños y deberías pensar en cómo solucionarlos. Los tipos anónimos no deben pasarse, especialmente no como modelos a una vista. –

+0

@Mattias: Desafortunadamente, la vida no es tan simple. Por ejemplo, considere el caso en el que selecciono algunas columnas de diferentes tablas, incluida una matriz de objetos seleccionados utilizando una consulta interna LINQ. Por lo que sé, no hay forma de devolverlo como un solo objeto EF, tiene * que ser un tipo nuevo, y la definición de un nuevo tipo concreto para cada consulta como esta es ridículamente engorroso. –

+0

Me parece que tienes un modelo bastante malo. Su objeto debe tener las referencias que necesita y puede simplemente usar el método "Include()" en EF (para cargar esos datos). Si deja de pensar en los datos como columnas diferentes en diferentes tablas, y más acerca de su modelo (más OO), será mucho más fácil trabajar con ellos. En pocas palabras: si sientes la necesidad de pasar tipos anónimos, lo más probable es que estés haciendo algo mal. –

Respuesta

1

Puesto que nadie siquiera intentó responder a mi pregunta, voy a contestar yo mismo ..

Resulta, C# 4.0 soporta pato-escribir - lo llaman dynamic typing. Sin embargo, en el uso de tipos dinámicos para devolver los tipos anónimos, se pierde los beneficios de tipos fuertes:

  • tiempo de compilación tipo de comprobación de
  • Rendimiento
  • Intellisense

He abierto una solicitud de función para tener tipos de devolución anónima fuertemente tipados here - si cree que esto sería una adición útil a C# 5, ¡siga el enlace y avísele al equipo de .Net!

3

Los tipos anónimos están diseñados principalmente para ser utilizados dentro de un método. No son adecuados para la comunicación entre métodos.

Si tiene que pasar una serie de datos entre dos funciones de la mejor manera es crear un nuevo tipo acomodando los datos o utilizar un perdedor como agrupación Tuple<T1,T2> o KeyValuePair<TKey,TValue>

+0

con la excepción de un escenario basado en la reflexión, en cuyo caso hay un par de buenos usos para ellos (en el MVC framework html helpers por ejemplo) –

+0

@Jared: Excepto que con LINQ, eso no es cierto en absoluto - objetos LINQ Sin duda, están destinados a ser pasados ​​por alto, pero simplemente no puede hacerlo en C# debido a limitaciones de idioma. Sin embargo, * se puede * hacer en VB.net. –

+0

@BlueRaja, lo siento, eso es incorrecto. ** Pueden ** transmitirse en cualquier idioma como 'System.Object'. No pueden transmitirse con fuerza en ninguno de los dos idiomas, ya que los tipos anónimos son muy anónimos. No se pueden definir directamente en ningún lugar que aparezca en los metadatos. En VB.net (y C# 4.0) puede solucionar esto accediendo a ellos de manera débilmente tipada, pero eso no es lo que el OP está pidiendo. – JaredPar

4

utilizar una capa de vista del modelo. Tu vista debe saber qué se mostrará. Supongo que es posible crear una vista que simplemente formatea una matriz multidimensional de datos, pero esa no es exactamente la mejor razón para ir con una solución MVC. Sin embargo, puede llenar un modelo de vista con un objeto anónimo para su consumo en su vista.

2

¿Qué tal esto?

Supongo que tiene una clase de entidad para su tabla 'myTable' (llamémosla 'MyTableEntity'), entonces ¿por qué no crea una instancia de un nuevo objeto MyTableEntity y usa el inicializador de objetos para llenar solo las columnas que desea?

return (from o in myTable select new MyTableEntity { AColumn = o.column }); 

Esto no se traducirá en un SELECT * como lo pidió, pero usted todavía tiene una manera de pasar un objeto inflexible de tipos a una vista.

Tienes que tener cuidado de solo hacer uso de las propiedades inicializadas dentro de la vista y eso es todo.

¿Tiene sentido para usted?

+0

Es una buena idea. Lo probaré en el trabajo cuando tenga la oportunidad (al menos no por unos días) –

0

En .NET 4.0 Los tipos anónimos se pueden convertir fácilmente a ExpandoObjects y, por lo tanto, todos los problemas se solucionan con la sobrecarga de la conversión. Salida here

0

Usted puede convertir fácilmente los tipos anónimos en objetos dinámicos, aquí es la simple aplicación de Donymous objetos (objetos anónimos dinámico) que pueden poblar desde el objeto Anónimos o DataReader.

Cuestiones relacionadas