これが最善の方法かどうかはわかりませんが、Reflector を使用して Microsoft.Office.Server.Search.Connector.BDC.BdcSecurityTrimmer をリバース エンジニアリングすることで、これを機能させることができました。これを少し単純化するために、ID 値のみが必要でした。
以下は、セキュリティ トリマーに提供された documentCrawlUrls の配列を取得し、BDC モデル ファイルで定義されている主キーの配列に変換するコードです。それらを取得したら、さらにカスタム .NET コードを使用してセキュリティ トリミングを決定できます。
私のセキュリティ トリマー (ISecurityTrimmer2) の CheckAccess() には、次のものがあります。
String[] ids = GetIds(documentCrawlUrls);
次に、次のプライベートメソッドがあります。
private string[] GetIds(IList<string> documentCrawlUrls)
{
string[] ids = new String[documentCrawlUrls.Count];
for (int i = 0; i < documentCrawlUrls.Count; i++)
{
try
{
string url = documentCrawlUrls[i];
Identity identity = null;
IEntity entity = null;
ILobSystemInstance lsi = null;
ParseUri(url, out entity, out identity, out lsi);
if (identity != null)
{
object[] values = identity.GetIdentifierValues();
if (values.Length > 0)
{
ids[i] = values[0].ToString();
}
}
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine("Error: " + ex.Message);
}
}
return ids;
}
私は SPBdcUri クラスを書き直したくありませんでした。これは内部であるため、リフレクションでごまかします。現在、効率を改善できるように、out パラメータの 1 つだけを使用しています。リフレクションに頼るのではなく、SPBdcUri の必要な部分を書き直すことができます。
private void ParseUri(string crawlUri, out IEntity entity, out Identity identity, out ILobSystemInstance lsi)
{
//SPBdcUri uri = new SPBdcUri(new Uri(crawlUri));
AssemblyName assemblyName = new AssemblyName("Microsoft.Office.Server.Search.Connector, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");
Assembly assembly = Assembly.Load(assemblyName);
Type spBdcUriType = assembly.GetType("Microsoft.Office.Server.Search.Connector.BDC.SPBDC.SPBdcUri");
object uri = Activator.CreateInstance(spBdcUriType,
BindingFlags.NonPublic | BindingFlags.Instance,
null, new object[] { new Uri(crawlUri) }, System.Globalization.CultureInfo.CurrentCulture);
//uri.DoOverrideBDCThrottlingLimits = false;
spBdcUriType.InvokeMember("DoOverrideBDCThrottlingLimits",
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
null, uri, new object[] { false });
//entity = uri.Entity;
object entityObj = spBdcUriType.InvokeMember("Entity",
BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty,
null, uri, null);
entity = (IEntity)entityObj;
//identity = uri.Identity;
object identityObj = spBdcUriType.InvokeMember("Identity",
BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty,
null, uri, null);
identity = (Identity)identityObj;
//lsi = uri.LobSystemInstance;
object lsiObj = spBdcUriType.InvokeMember("LobSystemInstance",
BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty,
null, uri, null);
lsi = (ILobSystemInstance)lsiObj;
}
ああ、ここに私の「使用」ステートメントがあります:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Microsoft.BusinessData.MetadataModel.Collections;
using Microsoft.BusinessData.MetadataModel;
using Microsoft.BusinessData.Runtime;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.BusinessData.SharedService;
using Microsoft.Office.Server.Search.Query;