2011-05-26 19 views
5

tengo Asp.net Profile.Location propiedad de perfil, sexo, etc.Cómo consultar desde ASP.NET Propiedades del perfil utilizando LINQ

i necesidad de obtener la lista de todos los usuarios cuya ubicación pertenece a "Londres" y Sexo masculino =

¿Cómo se realiza una búsqueda en Asp.net perfil usando LINQ

+0

necesito buscar y filtrar según los campos de perfil. pero todos los valores se almacenan en una sola cadena en la tabla aspnet_Profile. y no es recomendable consultar desde la tabla aspnet_profile. Puedo usar ProfileManager.GetAllProfiles() para obtener una colección de profileInfo. y, básicamente, tratando de filtrar utilizando LINQ – Bitlancer

+1

¿no puede hacer consultas linq contra la colección GetAllProfiles? Si es así, consulte http://programmersunlimited.wordpress.com/2011/01/08/linqqer-exposing-linq-extensions-on-non-ienumerableiqueriable-collections/ mirando a MSDN se muestra el tipo de devolución System.Web.Profile .ProfileInfoCollection es ICollection, IEnumerable lo que significa que no obtendrá Linq en él. Use el código del enlace para obtener la funcionalidad de Linq. –

+0

El objeto ProfileInfo solo contiene información muy básica como UserName o LastActivityDate, NO contiene los campos personalizados definidos en web.config. Por lo tanto, incluso si Linq está disponible en la Colección, no le permitirá filtrar sus campos personalizados. Necesita un método que devuelva una colección de objetos ProfileBase, y ninguno de los métodos proporcionados lo permita. –

Respuesta

0

no, no se puede hacer esto a través del proveedor de perfil por defecto de ASP.NET (que guarda los datos del perfil en un solo campo de cadena en la base de datos) aunque todavía puede hacer esto después de separar los datos de perfil en otra tabla de base de datos (que es un enfoque común, así como almacenar los datos de su perfil en otra t capaz y cablearlo con la tabla de usuarios por defecto a través de la clave GUID de usuario), entonces puede usar LINQ para consultar los datos de sus perfiles de usuario.

2

En realidad, puedes hacerlo. Pero hay que poner un par de cosas en su lugar primero:

  1. Una función que se analiza y devuelve la propiedad serializada/valora
  2. Opcionalmente, una visión que llama a la función para cada fila de usuario. Esto es opcional porque algunos ORM admiten consultas de composición con funciones definidas por el usuario. Recomiendo poner la vista en su lugar de todos modos.

Aquí hay una función CLR que escribí que analiza los valores de las columnas PropertyNames y PropertyValuesString de la tabla aspnet_Profile. Devuelve una tabla con una columna Propiedad y una columna Valor.

using System.Collections; 
using System.Collections.Generic; 
using System.Data.SqlTypes; 
using System.Linq; 
using System.Text.RegularExpressions; 
using Microsoft.SqlServer.Server; 

public partial class UserDefinedFunctions 
{ 
    private static readonly Regex ProfileRegex = new Regex(@"([a-zA-Z]+):[A-Z]:(\d+):(\d+)"); 

    [SqlFunction(FillRowMethodName = "FillProfileRow",TableDefinition="Property nvarchar(250), Value nvarchar(2000)")] 
    public static IEnumerable ParseProfileString(SqlString names, SqlString values) 
    { 
     var dict = ProfileRegex 
      .Matches(names.Value) 
      .Cast<Match>() 
      .ToDictionary(
       x => x.Groups[1].Value, 
       x => values.Value.Substring(int.Parse(x.Groups[2].Value), int.Parse(x.Groups[3].Value))); 

     return dict; 
    } 

    public static void FillProfileRow(object obj, out string Property, out string Value) 
    { 
     var x = (KeyValuePair<string, string>) obj; 
     Property = x.Key; 
     Value = x.Value; 
    } 
}; 

Despliegue esa función y luego cree una vista para los datos de perfil de su usuario. Aquí hay un ejemplo:

CREATE VIEW UsersView 
AS 

SELECT * 
FROM (
    SELECT u.UserId 
     ,u.Username 
     ,m.Email 
     ,f.Property 
     ,f.Value 
    FROM aspnet_Profile p 
    INNER JOIN aspnet_Users u ON p.UserId = u.UserId 
    INNER JOIN aspnet_Membership m ON m.UserId = u.Userid 
    INNER JOIN aspnet_Applications a ON a.ApplicationId = m.ApplicationId 
    CROSS APPLY ParseProfileString(p.PropertyNames, p.PropertyValuesString) f 
    WHERE a.ApplicationName = 'MyApplication' 
    ) src 
pivot(min(value) FOR property IN (
      -- list your profile property names here 
      FirstName, LastName, BirthDate 
      )) pvt 

Voila, puede consultar la vista con SQL o el ORM de su elección. Escribí éste en LINQPad:

from u in UsersView 
where u.LastName.StartsWith("ove") 
select u 
+0

Doy +1, me gusta el poder de Linq y RegEx que usaste en la función ParseProfileString(). – bau

+0

Gracias, @bau.Me gusta pensar en secuencias y funciones, por lo que mi código termina pareciéndose a esto la mayor parte del tiempo. –

0

considerar el uso de algo como esto:

matches = 
     matches.Union(
      memberDB.aspnet_Profile 
      .Where("it.PropertyValuesString Like @first", 
      new ObjectParameter("first", "%<FirstName>%" + firstName + "%</FirstName>%") 
      ).Select(p => p.UserId)); 

probablemente debería mencionar que hemos creado un archivo edmx de nuestra base de datos de miembros. Dicho esto, consideraría mover toda esa información interesante en sus propias tablas en la base de datos de su aplicación cuando tenga la oportunidad.

Cuestiones relacionadas