Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
211 views
in Technique[技术] by (71.8m points)

c# - How to Query from Asp.Net Profile Properties using LINQ

I have Asp.net profile property Profile.Location, Gender etc

i need to get list of all users whose Location belongs to "London" and Gender = male

how do i perform a search on Asp.net Profile using LINQ

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Actually, you can do it. But you need to put a couple of things in place first:

  1. A function that parses and returns the serialized property/values
  2. Optionally, a view that calls the function for each user row. This is optional because some ORM's support composing queries with user defined functions. I recommend putting the view in place anyway.

Here's a CLR function that I wrote that parses the PropertyNames and PropertyValuesString column values from the aspnet_Profile table. It returns a table with a Property column and a Value column.

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;
    }
};

Deploy that function and then create a view for your user's profile data. Here's an example:

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, you can query the view with SQL or the ORM of your choice. I wrote this one in Linqpad:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...