问题
I'm trying to connect to INCA through the .NET API in order to navigate the folder structure of an ASAP2 project. Specifically, I want to get an object that represents the "Target" folder that I've highlighted below.
This is proving pretty tricky--The API provides a ton of classes that have the name "Folder" in them: Folder
, Asap2ProjectFolder
, and IncaFolder
. So what do I need to know in order to retrieve the "Target" folder?
回答1:
Your first impulse might be to think of the Target folder as existing on a long path like USER A\Demo\Demo03\Foo\Bar\Baz\Target
. Unfortunately, INCA doesn't have a mechanism to do this--instead, you have to retrieve the lowest item in the Database Objects portion of the path, and then query that item for the Datasets portion of the path.
From the database root, we need to drill down to Demo03, which is an Asap2Project
:
USER A\Demo\Demo03
From within Demo03, we then need to drill down to Target, which is an Asap2ProjectFolder
:
Foo\Bar\Baz\Target
The first part is pretty simple--we can connect to INCA and get the Demo03 Asap2Project in just a few lines of code:
Asap2ProjectFolder targetFolder = null;
Inca myIncaInstance = new Inca();
DataBase myDB = myIncaInstance.GetCurrentDataBase();
DataBaseItem tempItem = myDB.GetItemInFolder("Demo03", "USER A\\Demo");
if ((tempItem != null) &&
(tempItem.IsAsap2Project()))
{
Asap2Project demoProject = (Asap2Project)tempItem;
// Next step: grab the "Target folder!"
}
Now, here's where things get a bit tricky.
If we were trying to get a DataSet
like Demo03_1, we could use a call like demoProject.GetDataSetForName("Demo03\\Demo03_1")
. The problem is, this method only works for objects of type DataSet. So we can't use it to retrieve a folder like Foo\Bar\Baz\Target
. If you've poked around in the API a bit, you might have tried something like this:
Asap2ProjectFolder tempProjFolder = demoProject.GetTopFolderNamed("Foo");
tempItem = tempProjFolder.GetDataBaseItem("Bar\\Baz\\Target"); // Won't work.
tempItem = tempProjFolder.GetSubFolder("Bar\\Baz\\Target"); // This won't either.
Turns out that we need to be a bit more resourceful. Let's make GetItemInFolder()
extension methods for the Asap2Project
and Asap2ProjectFolder
classes, so those classes will have the same item-retrieval flexibility as the DataBase
class:
namespace IncaExtensions
{
public static class GetItemInFolderExtensions
{
/// <summary>
/// Gets a DataBaseItem from an Asap2Project in an arbitrary subfolder.
/// </summary>
/// <param name="project">The current Asap2Project</param>
/// <param name="itemName">The name of the item that we want to retrieve</param>
/// <param name="folderName">The path, delimited by backslashes ('\\')</param>
/// <returns>A DataBaseItem matching the request.
/// If no matching item is found, or if the path is invalid, return null.
/// </returns>
public static DataBaseItem GetItemInFolder(this Asap2Project project,
string itemName,
string folderName)
{
DataBaseItem returnItem = null;
if ((folderName != null) &&
(itemName != null))
{
string folderToken = PluckPathToken(ref folderName);
Asap2ProjectFolder subFolder =
project.GetTopFolderNamed(folderToken);
if (subFolder != null)
{
returnItem = subFolder.GetItemInFolder(itemName, folderName);
}
}
return returnItem;
}
/// <summary>
/// Recursive call that returns a DataBaseItem in the target path.
/// </summary>
/// <param name="folder">The Asap2ProjectFolder to drill down</param>
/// <param name="itemName">The name of the item that we want to retrieve</param>
/// <param name="folderName">The path, delimited by backslashes ('\\')</param>
/// <returns>A DataBaseItem matching the request.
/// If no matching item is found, or if the path is invalid, return null.
/// </returns>
public static DataBaseItem GetItemInFolder(this Asap2ProjectFolder folder,
string itemName,
string folderName)
{
DataBaseItem returnItem = null;
if ((folderName != null) &&
(itemName != null))
{
string folderToken = PluckPathToken(ref folderName);
Asap2ProjectFolder subFolder =
(Asap2ProjectFolder)folder.GetSubFolder(folderToken);
if (subFolder != null)
{
returnItem = subFolder.GetItemInFolder(itemName, folderName);
}
}
else
{
returnItem = folder.GetDataBaseItem(itemName);
}
return returnItem;
}
/// <summary>
/// Removes a backslash-delimited token from a string and shortens the
/// input string.
/// </summary>
/// <param name="folderName">Backslash-delimited path. This will be
/// shortened each time a token is removed.</param>
/// <returns>The latest path token</returns>
static string PluckPathToken(ref string folderName)
{
int slashIdx = folderName.IndexOf('\\');
// If folderName has path tokens, extract the first token and
// shorten folderName accordingly.
string folderToken = (slashIdx > -1) ?
folderName.Substring(0, slashIdx) : folderName;
folderName = (slashIdx > -1) ?
folderName.Substring(slashIdx + 1) : null;
return folderToken;
}
}
}
This makes it super-easy to grab items out of an Asap2Project
or Asap2ProjectFolder
. To grab the Target folder, we only need the following calls:
using IncaExtensions;
...
Asap2ProjectFolder targetFolder = null;
Inca myIncaInstance = new Inca();
DataBase myDB = myIncaInstance.GetCurrentDataBase();
DataBaseItem tempItem = myDB.GetItemInFolder("Demo03", "USER A\\Demo");
if ((tempItem != null) &&
(tempItem.IsAsap2Project()))
{
Asap2Project demoProject = (Asap2Project)tempItem;
targetFolder = (Asap2ProjectFolder)demoProject.GetItemInFolder("Target", "Foo\\Bar\\Baz");
}
来源:https://stackoverflow.com/questions/18214951/in-etas-inca-is-there-a-way-to-quickly-retrieve-an-item-from-an-arbitrary-path