none
Filtrar información de acuerdo al usuario actual logeado asp.net mvc3 RRS feed

  • Pregunta

  • Actualmente estoy desarrollando un proyecto con asp.net mvc3, he instalado por medio de nuget los "asp.net universal providers" esto con el fin de manejar el logeo de los usuarios y los roles dentro de la aplicación, adicionalmente estoy utilizando entity framework para hacer las consultas a la base de datos, lo que he hecho es añadir a la carpeta models un entity data model para crear el modelo de la base de datos luego sobre la superficie del modelo le utilizado la opcion de ""agregar elemento de generacion de codigo" y luego le he dado en la opcion "ADO.net Dbcontext generator", esto me ha creago unas clases que corresponden a cada tabla de la base de datos.

    Luego he creado unos controller utilizando la opcion de "controller con read/write actions and views, using entity framework" esto me ha creado todo lo necesario (vistas y acciones) para crear, consultar, modificar y eliminar datos de la base de datos. he hecho esto para cada tabla de la base de datos.

    Necesito que cada usuario pueda ver solo la información correspondiente a su empresa, es decir cada usuario esta asociado a una empresa dentro de la aplicación, para estos todas las consultas linq que hago a la base de datos debo filtrarlas por empresa.

    Ej: tengo relaciones a nivel de base de datos entre unas tablas llamadas fabricante, software y empresa, como lo que quiero es que cuando el usuario se logee dentro de la aplicación pueda ver solo los fabricantes de su empresa no todos lo que he hecho es en el controller colocar este codigo:

     

    public class FabricanteController : Controller

        {

            private SamEntities db = new SamEntities();


            //

            // GET: /Fabricante/


            public ViewResult Index()

            {

                MembershipUser myObject = Membership.GetUser();

                string User = myObject.ProviderUserKey.ToString();

                //string user = Membership.GetUser().ProviderUserKey.ToString();


                var query = from e in db.UsuarioEmpresa

                            where e.UserId.ToString() == user

                            select e.IdEmpresa;


                

                var query2 = from f in db.Fabricantes

                             join s in db.Software

                                  on f.Id equals s.Id_Fabricante

                             join e in db.Empresas

                             on s.Id_empresa equals query.FirstOrDefault()

                             select f;  



                return View(query2.ToList());

            }

    }

    Pero cuando pongo en ejecución la aplicación me da el siguiente error:

    "LINQ to Entities no reconoce el método 'System.String ToString()' del método, y este método no se puede traducir en una expresión de almacén."

    ¿Quisiera saber como puedo hacer esto? poder filtrar la información por empresa de acuerdo al usuario logeado.

    miércoles, 18 de enero de 2012 13:29

Respuestas

  • Muy buenas!

    El problema lo tienes en:

    var query = from e in db.UsuarioEmpresa
    where e.UserId.ToString() == user
    select e.IdEmpresa;
    <br/>
    

    Concretamente en el ToString() que usas. Lo que ocurre es que Linq To Sql, debe traducir esta query LINQ a SQL para ejecutar en la base de datos y se encuentra una llamada a ToString(). Por lo que buscará un método ToString() en SQL y al no existir dará error.

    Esas cosas ocurren en LINQ: La expresión que tu uses puede ser válido según de donde vengan realmente los datos (no es lo mismo que estén en memoria, en SQL Server, en otra base de datos).

    Debes eliminar ese ToString(). Estás haciendo esto:

    string User = myObject.ProviderUserKey.ToString();
    

    Hay alguna necesidad de que eso sea un string? Es decir porque llamas al ToString() del ProviderUserKey. En lugar de llamar a ToString() debes convertir el valor devuelto por ProviderUserKey al tipo de datos real que sea. Si en tu BBDD tienes enteros debes hacer:

    int user = (int)myObject.GetProviderUserKey();
    

    Si tienes GUIDs (lo que usa el proveedor por defecto si no lo has modificado), entonces debes hacer:

    Guid user = (Guid)myObject.GetProviderUserKey();
    

    Y luego en la query LINQ eliminas el .ToString() que tienes y te debería funcionar correctamente.

    Un saludo!

    PD: Si NO sabes de que tipo real es el ProviderUserKey, puedes averiguarlo, poniendo un breakpoint en la la línea donde llamas a GetProviderKey() y añadir un watch que sea "myObject.GetProviderUserKey()". VS invocará al método y te dirá el valor y su tipo (si es int, Guid, string, ...). De hecho, este tipo DEBERIA coincidir con el tipo de la propiedad UserId de db.UsuarioEmpresa.


    Eduard Tomàs Blog: http://geeks.ms/blogs/etomas -- Twitter: eiximenis
    • Propuesto como respuesta David Peláez viernes, 20 de enero de 2012 21:10
    • Marcado como respuesta Eder Costa viernes, 26 de octubre de 2012 13:31
    miércoles, 18 de enero de 2012 14:13

Todas las respuestas

  • Muy buenas!

    El problema lo tienes en:

    var query = from e in db.UsuarioEmpresa
    where e.UserId.ToString() == user
    select e.IdEmpresa;
    <br/>
    

    Concretamente en el ToString() que usas. Lo que ocurre es que Linq To Sql, debe traducir esta query LINQ a SQL para ejecutar en la base de datos y se encuentra una llamada a ToString(). Por lo que buscará un método ToString() en SQL y al no existir dará error.

    Esas cosas ocurren en LINQ: La expresión que tu uses puede ser válido según de donde vengan realmente los datos (no es lo mismo que estén en memoria, en SQL Server, en otra base de datos).

    Debes eliminar ese ToString(). Estás haciendo esto:

    string User = myObject.ProviderUserKey.ToString();
    

    Hay alguna necesidad de que eso sea un string? Es decir porque llamas al ToString() del ProviderUserKey. En lugar de llamar a ToString() debes convertir el valor devuelto por ProviderUserKey al tipo de datos real que sea. Si en tu BBDD tienes enteros debes hacer:

    int user = (int)myObject.GetProviderUserKey();
    

    Si tienes GUIDs (lo que usa el proveedor por defecto si no lo has modificado), entonces debes hacer:

    Guid user = (Guid)myObject.GetProviderUserKey();
    

    Y luego en la query LINQ eliminas el .ToString() que tienes y te debería funcionar correctamente.

    Un saludo!

    PD: Si NO sabes de que tipo real es el ProviderUserKey, puedes averiguarlo, poniendo un breakpoint en la la línea donde llamas a GetProviderKey() y añadir un watch que sea "myObject.GetProviderUserKey()". VS invocará al método y te dirá el valor y su tipo (si es int, Guid, string, ...). De hecho, este tipo DEBERIA coincidir con el tipo de la propiedad UserId de db.UsuarioEmpresa.


    Eduard Tomàs Blog: http://geeks.ms/blogs/etomas -- Twitter: eiximenis
    • Propuesto como respuesta David Peláez viernes, 20 de enero de 2012 21:10
    • Marcado como respuesta Eder Costa viernes, 26 de octubre de 2012 13:31
    miércoles, 18 de enero de 2012 14:13
  • Hola eduard

    Muchas gracias, hize las correcciones que me indicaste y funciono perfectamente.

    Agradezco tu colaboración

     

    Cordial saludo.

    miércoles, 18 de enero de 2012 17:22