none
Crear instancia del contexto en EF RRS feed

  • Pregunta

  • Buenos días:

    Llevo horas dando vueltas a un error que me da al crear una instancia del contexto de EF y no soy capaz de dar con qué es lo que hago mal. Les pongo un ejemplo, en WPF y EF, para simplificar lo dejamos en dos proyectos, uno hace de Model y ViewModel a la vez (en el programa completo que sí cumple el patrón MVVM completo el error es el mismo, pero así es más fácil verlo), y otro con las Views. Dentro del ModelViewModel hay un EF de la base de datos AdventureWorksLT, sólo con la tabla Customers (pero da igual qué base de datos y qué tabla pongamos para el error que me da, porque he probado con otras bases de datos y otras tablas).

    Bien, el código de MainWindow.xalm es el siguiente:

    <ribbon:RibbonWindow x:Class="MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
            xmlns:vm="clr-namespace:ModelViewModel;assembly=ModelViewModel"
            Title="MainWindow" 
            x:Name="RibbonWindow"
    		Width="640" Height="480">
        
        <Window.DataContext>
            <vm:Class1/>      
        </Window.DataContext>
    
        <Grid x:Name="LayoutRoot">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    
            <ribbon:Ribbon x:Name="Ribbon">
    
                        <ribbon:RibbonButton x:Name="Button1"
                                             LargeImageSource="Images\LargeIcon.png"
                                             Label="{Binding Path=Nombre}" />
            </ribbon:Ribbon>
        </Grid>
    </ribbon:RibbonWindow>
    

    Simplemente tiene un botón en el Ribbon que cogerá por Label lo que nos devuelva la propiedad "Nombre" del ModelViewModel. Y el proyecto ModelViewModel sólo tiene una clase, llamada Class1, que tiene el siguiente código:

    Public Class Class1
    
        Private contexto As AdventureWorksLTEntities
    
        Public Sub New()
            'contexto = New AdventureWorksLTEntities
        End Sub
        Public ReadOnly Property Nombre As String
            Get
                Return "No hace nada, sólo ejemplo"
            End Get
        End Property
    End Class
    


    Pues bien, si lo ejecuto tal cual, funciona bien, sale el ribbon con el texto "No hace nada, sólo ejemplo" en el botón, pero si quito el comentario de la línea contexto = New AdventureWorksLTEntities, entonces me sale el siguiente error:

    'La invocación del constructor del tipo 'ModelViewModel.Class1' que coincide con las restricciones de enlace especificadas produjo una excepción.' (número de línea: '10'; posición de línea: '6').

    ¿Por qué es eso? He pensado que igual para trabajar en el proyecto biblioteca de clases con EF tengo que añadir alguna referencia, o que estoy instanciando algo mal, pero llevo horas dándole vueltas y no soy capaz de verlo. Lógicamente este es un ejemplo tonto, con un código que no vale para nada, pero en el programa que estoy intentando desarrollar voy a necesitar acceder al EF de Model para poder hacer mi ViewModel, y me sale el mismo error. Me gustaría saber a qué se debe, qué  hago mal.

    ¿Alguien me puede ayudar, por favor? Lo agradecería mucho, porque soy nuevo en esto y ahora mismo estoy atascado.

    Muchas gracias por anticipado.


    Carlos Adrián Martínez
    miércoles, 4 de enero de 2012 9:32

Respuestas

  • Hola Carlos,

    Te comento:

    El constructor por defecto del contexto de EF va a utilizar la primera cadena de conexión que encuentre en el fichero de configuración de donde este definido el modelo.

    Posibles soluciones que puedes utilizar:

    - Si defines el Model de EF en una proyecto de tipo DLL (digamos lo normal):

        * Defines un fichero App.config con la cadena de conexión.

         * Al instanciar el contexto, no utilizas el constructor normal, y lo invocas enviando la cadena de conexion REAL que quieres utilizar.

     

    Un saludo.


    Javier Torrecilla
    Para el correcto funcionamiento, y que otros usuarios se puedan beneficiar de la solucion de esta pregunta por favor marca las respuestas que te hayan ayudado como "Respuesta".
    Si la respuesta te ha sido util Votala.
    Mi Blog: Jtorrecilla
    Enlace a Faq de Winforms en Ingles Muy bueno
    TabControl con Mejoras
    • Marcado como respuesta Carlos Adrián miércoles, 4 de enero de 2012 12:54
    miércoles, 4 de enero de 2012 12:18
  • Ya lo he arreglado, Javier, te marco como respuesta. Pongo aquí lo que he hecho por si le vuelve a pasar a alguien, aunque en realidad no tengo muy claro por qué es así.

    - He borrado mi modelo EF.

    - He borrado todas las connectionStrings de todos los app.config (de hecho he borrado todos los app.config excepto el del proyecto Views)

    - He creado el modelo en el proyecto Views, para que me modifique el app.config de ese proyecto en particular, en vez de modificarme el del proyecto Models (que según yo lo veo sería lo lógico, pero parece ser que no es así).

    - He movido el modelo EF del proyecto Views al proyecto Models, dejando la cadena de conexión en el app.config del proyecto Views (que es lo que no entiendo, pero bueno, así funciona).

     

    Y al ejecutar, ya ha funcionado. ¿Por qué? No tengo ni idea, pero funciona :)

     

    Muchas gracias de todos modos.

     


    Carlos Adrián Martínez
    • Marcado como respuesta Carlos Adrián miércoles, 4 de enero de 2012 12:58
    miércoles, 4 de enero de 2012 12:58

Todas las respuestas

  • Ya he conseguido que funcione en el ejemplo que he mandado antes, pero ahora estoy más liado aún. El problema viene por el archivo app.config. Al crear el modelo con EF crea también el fichero app.config. En el ejemplo que he mandado antes, el que daba el error, simplemente moviendo el app.config del proyecto ModelViewModel (el que contiene el modelo) al otro proyecto (el que contiene las vistas), se soluciona y ya no da el error.

    Resumiendo:

    - Si creo directamente el modelo EF en el proyecto ModelViewModel, da el error que comentaba arriba

    - Si creo el modelo de EF en el proyecto de las views y luego lo muevo al proyecto ModelViewModel, funciona bien

    - Si creo el modelo EF en el proyecto ModelViewModel directamente, pero luego muevo el archivo app.config que me crea automática al proyecto de las views, también funciona.

    Algo he progresado, ya consigo hacer que funcione ese ejemplo simple que puse, pero ¿alguien me puede explicar por qué? He pensado que podría ser por que añade a app.config las connectionstrings del modelo EF, pero ¿no sería más lógico que esas connectionstrings estuviesen en el proyecto ModelViewModel, que es el que tiene el modelo? ¿por qué tienen que estar en el otro proyecto?

    No entiendo nada, ¿alguien con experiencia me puede explicar lo que está pasando, por favor?

     

    Muchas gracias


    Carlos Adrián Martínez
    miércoles, 4 de enero de 2012 12:03
  • Hola Carlos,

    Te comento:

    El constructor por defecto del contexto de EF va a utilizar la primera cadena de conexión que encuentre en el fichero de configuración de donde este definido el modelo.

    Posibles soluciones que puedes utilizar:

    - Si defines el Model de EF en una proyecto de tipo DLL (digamos lo normal):

        * Defines un fichero App.config con la cadena de conexión.

         * Al instanciar el contexto, no utilizas el constructor normal, y lo invocas enviando la cadena de conexion REAL que quieres utilizar.

     

    Un saludo.


    Javier Torrecilla
    Para el correcto funcionamiento, y que otros usuarios se puedan beneficiar de la solucion de esta pregunta por favor marca las respuestas que te hayan ayudado como "Respuesta".
    Si la respuesta te ha sido util Votala.
    Mi Blog: Jtorrecilla
    Enlace a Faq de Winforms en Ingles Muy bueno
    TabControl con Mejoras
    • Marcado como respuesta Carlos Adrián miércoles, 4 de enero de 2012 12:54
    miércoles, 4 de enero de 2012 12:18
  • Ya lo he arreglado, Javier, te marco como respuesta. Pongo aquí lo que he hecho por si le vuelve a pasar a alguien, aunque en realidad no tengo muy claro por qué es así.

    - He borrado mi modelo EF.

    - He borrado todas las connectionStrings de todos los app.config (de hecho he borrado todos los app.config excepto el del proyecto Views)

    - He creado el modelo en el proyecto Views, para que me modifique el app.config de ese proyecto en particular, en vez de modificarme el del proyecto Models (que según yo lo veo sería lo lógico, pero parece ser que no es así).

    - He movido el modelo EF del proyecto Views al proyecto Models, dejando la cadena de conexión en el app.config del proyecto Views (que es lo que no entiendo, pero bueno, así funciona).

     

    Y al ejecutar, ya ha funcionado. ¿Por qué? No tengo ni idea, pero funciona :)

     

    Muchas gracias de todos modos.

     


    Carlos Adrián Martínez
    • Marcado como respuesta Carlos Adrián miércoles, 4 de enero de 2012 12:58
    miércoles, 4 de enero de 2012 12:58
  • Podrías mostrar un pantallazo de tu explorador de soluciones?
    Javier Torrecilla
    Para el correcto funcionamiento, y que otros usuarios se puedan beneficiar de la solucion de esta pregunta por favor marca las respuestas que te hayan ayudado como "Respuesta".
    Si la respuesta te ha sido util Votala.
    Mi Blog: Jtorrecilla
    Enlace a Faq de Winforms en Ingles Muy bueno
    TabControl con Mejoras
    miércoles, 4 de enero de 2012 13:01

  • Carlos Adrián Martínez
    miércoles, 4 de enero de 2012 13:07
  • La solución es sencilla. Me apareció el mismo error hace poco: Tenía una clase A que heredaba MenuItem (WPF) creada debajo de la clase principal, esto con el fin de crear Menu Items personalizados. La Clase A tiene un método constructor que recibe como parámetro strings. En la clase principal estaba haciendo campos de tipo de la clase A, y estaba creando los objetos enseguida:

    enum B{ Primero, Segundo };
    
    public partial class MainWindow : Window {
    
        private A menuItem1 = new A(Enum.Primero);
    
        public MainWindow(){
            InitializeComponents();
        }
    }
    
    public class A : MenuItem {
        public A(string s){}
    }

    Al crearlos enseguida me arroja el mismo error que tienes. La solución es crear estos objetos en el constructor de la misma clase

    enum B{ Primero, Segundo };
    
    public partial class MainWindow : Window {
    
        private A menuItem1;
    
        public MainWindow(){
            InitializeComponents();
            menuItem1 = new A(Enum.Primero);
        }
    }
    
    public class A : MenuItem {
        public A(string s){}
    }
    

     

    Si te vuelve a pasar, intenta esta solución

    • Propuesto como respuesta LevanenG lunes, 30 de enero de 2012 17:22
    lunes, 30 de enero de 2012 17:21