如何使用 LINQ 从 Asp.Net 配置文件属性进行查询

发布于 2024-11-09 19:33:10 字数 123 浏览 3 评论 0原文

我有 Asp.net 配置文件属性 Profile.Location、性别等,

我需要获取位置属于“伦敦”且性别 = 男性的所有用户的列表

我如何使用 LINQ 在 Asp.net 配置文件上执行搜索

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梓梦 2024-11-16 19:33:10

事实上,你可以做到。但您需要首先准备好几件事:

  1. 一个解析并返回序列化属性/值的函数
  2. (可选)一个为每个用户行调用该函数的视图。这是可选的,因为某些 ORM 支持使用用户定义的函数编写查询。无论如何,我建议将视图放置到位。

下面是我编写的一个 CLR 函数,用于解析 aspnet_Profile 表中的 PropertyNames 和 PropertyValuesString 列值。它返回一个包含属性列和值列的表。

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

部署该函数,然后为用户的配置文件数据创建视图。下面是一个示例:

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

瞧,您可以使用 SQL 或您选择的 ORM 查询视图。我在 Linqpad 中写了这个:

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

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
尸血腥色 2024-11-16 19:33:10

不,您不能通过默认的 ASP.NET 配置文件提供程序(它将配置文件数据保存在数据库中的单个字符串字段中)来执行此操作,尽管您仍然可以在另一个数据库表中分离配置文件数据后执行此操作(这是一种常见的方法)以及将您的配置文件数据存储在另一个表中,并通过 User GUID 键将其与默认用户表连接),然后您可以使用 LINQ 查询您的用户配置文件数据。

No, you can't do this through the default ASP.NET profile provider (which saves profile data in a single string field in the database) though you still can do this after separating profile data in another database table (which is a common approach as well to store your profile data in another table and wire it with the default users table via the User GUID key), then you can use LINQ to query your users profiles data.

梦醒灬来后我 2024-11-16 19:33:10

考虑使用这样的东西:

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

我可能应该提到我们已经为我们的会员数据库创建了一个 edmx 文件。也就是说,当您有机会时,我会考虑将所有这些有趣的信息移动到应用程序数据库中自己的表中。

consider using something like this:

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

I should probably mention that we've created an edmx file for our membership database. That said, I'd consider moving all of that interesting information into it's own tables in your application database when you get a chance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文