天天看點

讓DotNetNuke 4.3.5使用SQL Full-text index 查找使用者資訊

近日在開發DotNetNuke系統時,要實作一個查找站内注冊使用者資訊的功能,我首先想到的就是系統自帶的使用者管理頁面,因為系統自帶的管理頁面,在功能上,已經實作了大部份我要的功能,比如按使用者名查找使用者,按使用者的其他Profile資訊查找。

但有一個問題,那就是DotNetNuke自帶的使用者管理的查找功能很弱,對于稍稍不常見的中文查找就會出現找不到的情況,特别是查找公司名稱,如果查找“北京三一重工有限公司”,如果使用者隻輸入“三一”是不會傳回任何結果的。那麼能不能搭一搭SQL的Full-text index search這個順風車呢?

經過一番研究(當中幾千字日後再寫.....),簡單的解決方案如下:

在SQL資料庫中找到如下的存儲過程:

SET QUOTED_IDENTIFIER ON 

GO

SET ANSI_NULLS ON 

ALTER  PROCEDURE dbo.[GetUsersByProfileProperty]

    @PortalId        int,

    @PropertyName   nvarchar(256),

    @PropertyValue  nvarchar(256),

    @PageIndex      int,

    @PageSize       int

AS

BEGIN

    -- Set the page bounds

    DECLARE @PageLowerBound INT

    DECLARE @PageUpperBound INT

    SET @PageLowerBound = @PageSize * @PageIndex

    SET @PageUpperBound = @PageSize - 1 + @PageLowerBound

    -- Create a temp table TO store the select results

    CREATE TABLE #PageIndexForUsers

    (

        IndexId int IDENTITY (0, 1) NOT NULL,

        UserId int

    )

    -- Insert into our temp table

    INSERT INTO #PageIndexForUsers (UserId)

        SELECT U.UserId 

        FROM   ProfilePropertyDefinition P

            INNER JOIN UserProfile UP ON P.PropertyDefinitionID = UP.PropertyDefinitionID 

            INNER JOIN Users U ON UP.UserID = U.UserID

        WHERE (PropertyName = @PropertyName) AND (PropertyValue LIKE @PropertyValue OR PropertyText LIKE @PropertyValue )

            AND (P.Portalid = @PortalId OR (P.PortalId Is Null AND @PortalId is null ))

        ORDER BY U.DisplayName

    SELECT  *

    FROM    vw_Users u, 

            #PageIndexForUsers p

    WHERE  u.UserId = p.UserId

            AND ( PortalId = @PortalId OR (PortalId Is Null AND @PortalId is null ))

            AND p.IndexId >= @PageLowerBound AND p.IndexId <= @PageUpperBound

    SELECT  TotalRecords = COUNT(*)

    FROM    #PageIndexForUsers

END

SET QUOTED_IDENTIFIER OFF 

1、在企業管理器中,為UserProfile表的PropertyValue和PropertyText建立全文檢索。

2、在SQL企業管理器中,點選“工具->查詢分析器(Query Analyer)" 運作以下代碼:

use DotNetNuke(請更換為你使用的資料庫名稱)

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[GetUsersByProfileProperty]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)

drop procedure [dbo].[GetUsersByProfileProperty]

CREATE PROCEDURE dbo.[GetUsersByProfileProperty]

        WHERE (PropertyName = @PropertyName) AND (contains(PropertyValue,@PropertyValue) OR contains(PropertyText,@PropertyValue ))

因為時間緊張,先寫到這裡,還有很多要補充的,并且這個解決方案直接改到了DotNetNuke系統的核心程式,不能向後相容,寫出來隻是提供參考,解一時之急,正确的做法應該是寫一個新的Provider,這個有時間再說吧。