En realidad, puedes hacerlo. Pero hay que poner un par de cosas en su lugar primero:
- Una función que se analiza y devuelve la propiedad serializada/valora
- 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
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
¿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. –
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. –