测试数据:20万记录的图层,30个字段
1、常规方式
gdb:耗时2846ms mdb:3293ms shp:5769ms
/// <summary>
/// 得到要素类某字段的唯一值
/// </summary>
/// <param name="FClass">要素类</param>
/// <param name="strFld">指定要得到唯一值的字段</param>
public List<string> GetUniqueValue(IFeatureClass FClass,string strFld)
{
List<string> plist = new List<string>();
using (ComReleaser comReleaser = new ComReleaser())
{
int idx = FClass.FindField(strFld);
var value = "";
IFeatureCursor cursor = FClass.Search(null, true);
comReleaser.ManageLifetime(cursor);
IFeature feature = null;
while ((feature = cursor.NextFeature()) != null)
{
value = feature.Value[idx].ToString();
if (!plist.Contains(value))
plist.Add(value);
}
}
return plist;
}
在获取多字段唯一值时比IQueryDef2接口慢了许多:
/// <summary>
/// 获取要素类唯一值
/// </summary>
/// <param name="pFeatureClass">要素类</param>
/// <param name="flds">字段集合</param>
/// <param name="queryFilter">筛选条件</param>
/// <returns></returns>
public static List<Dictionary<string,object>> GetUniqueValue(IFeatureClass pFeatureClass, List<string> flds,IQueryFilter queryFilter, out int fcount)
{
fcount = 0;
Dictionary<string, int> fldidx = new Dictionary<string, int>();
flds.ForEach(x => fldidx.Add(x, pFeatureClass.FindField(x)));
Dictionary<string, object> dic = new Dictionary<string, object>();
List<Dictionary<string, object>> lis = new List<Dictionary<string, object>>();
IFeatureCursor cursor = pFeatureClass.Search(queryFilter, true);
IFeature feature = null;
while ((feature = cursor.NextFeature()) != null)
{
fcount++;
foreach (var it in fldidx)
dic[it.Key] = feature.Value[it.Value];
if (!lis.Exists(x => x.SequenceEqual(dic)))
lis.Add(new Dictionary<string, object>(dic));
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(cursor);
return lis;
}
2、使用枚举
gdb: 耗时4972ms mdb:3987ms shp:7700ms
/// <summary>
/// 得到要素类某字段的唯一值
/// </summary>
/// <param name="pFeatureClass">要素类</param>
/// <param name="strFld">指定要得到唯一值的字段</param>
/// <returns>唯一值字符数据</returns>
public static List<string> GetUniqueValueWithEnum(IFeatureClass pFeatureClass, string strFld)
{
//定义List泛型
List<string> plist = new List<string>();
using (ComReleaser comReleaser=new ComReleaser())
{
//得到IFeatureCursor游标
IFeatureCursor pCursor = pFeatureClass.Search(null, false);
comReleaser.ManageLifetime(comReleaser);
//coClass对象实例生成
IDataStatistics pData = new DataStatisticsClass();
pData.Field = strFld;
pData.Cursor = pCursor as ICursor;
//枚举唯一值
IEnumerator pEnumVar = pData.UniqueValues;
//可记录总条数:int RecordCount=pData.UniqueValueCount;
pEnumVar.Reset();
while (pEnumVar.MoveNext())
{
plist.Add(pEnumVar.Current.ToString());
}
}
return plist;
}
3、使用IQueryDef2接口
gdb:耗时4390ms mdb:178ms shp:不支持
/// <summary>
/// 得到要素类唯一记录
/// </summary>
/// <param name="FClass"></param>
/// <param name="strFld">字段名(可以多个字段,以逗号相隔,例如:"DLBM,DLMC")</param>
/// <returns></returns>
public List<string> GetUniqueValueByQF(IFeatureClass FClass, string strFld)
{
List<string> plist = new List<string>();
Dictionary<string, string> dic = new Dictionary<string, string>();
using (ComReleaser comReleaser = new ComReleaser())
{
IDataset dataset = FClass as IDataset;
IFeatureWorkspace featureWorkspace = dataset.Workspace as IFeatureWorkspace;
// Create the QueryDef.
IQueryDef2 queryDef2 = (IQueryDef2)featureWorkspace.CreateQueryDef();
queryDef2.Tables = dataset.Name;
queryDef2.SubFields = $"Distinct {strFld}";
ICursor cursor = queryDef2.Evaluate2(true);
comReleaser.ManageLifetime(cursor);
int idx = 0;
switch (dataset.Workspace.WorkspaceFactory.GetType().Name)
{
case "AccessWorkspaceFactoryClass":
idx = cursor.FindField($"Distinct {strFld.Split(',')[0]}"); //在mdb中首个字段名会变为:$"Distinct XX"
break;
case "FileGDBWorkspaceFactoryClass":
idx = cursor.FindField(strFld.Split(',')[0]);
break;
}
var value = "";
IRow row = null;
while ((row = cursor.NextRow()) != null)
{
value = row.Value[idx].ToString();
plist.Add(value);
}
}
return plist;
}
获取多字段唯一值:
/// <summary>
/// 得到要素类唯一记录
/// </summary>
/// <param name="FClass"></param>
/// <param name="flds">字段集合</param>
/// <param name="strWhere">限制条件</param>
/// <returns></returns>
public static List<Dictionary<string, object>> GetUniqueValueByQF(IFeatureClass FClass, List<string> flds,string strWhere="")
{
List<Dictionary<string, object>> pdic = new List<Dictionary<string, object>>();
Dictionary<string, int> fldidx = new Dictionary<string, int>();
string fls = string.Empty;
for (int i = 0; i < flds.Count; i++)
{
fldidx[flds[i]] = i;
fls += $",{flds[i]}";
}
Dictionary<string, object> dic = new Dictionary<string, object>();
using (ComReleaser comReleaser = new ComReleaser())
{
IDataset dataset = FClass as IDataset;
IFeatureWorkspace featureWorkspace = dataset.Workspace as IFeatureWorkspace;
// Create the QueryDef.
IQueryDef2 queryDef2 = (IQueryDef2)featureWorkspace.CreateQueryDef();
queryDef2.Tables = dataset.Name;
queryDef2.SubFields = $"Distinct {fls.Substring(1)}";
if (!string.IsNullOrEmpty(strWhere))
queryDef2.WhereClause = strWhere;
ICursor cursor = queryDef2.Evaluate2(true);
comReleaser.ManageLifetime(cursor);
IRow row = null;
while ((row = cursor.NextRow()) != null)
{
foreach (var it in fldidx)
dic[it.Key] = row.Value[it.Value];
pdic.Add(new Dictionary<string, object>(dic));
}
}
return pdic;
}