问题
I have couple of providers created with a smartform:
ID Title
90 Doctor A
102 Doctor B
10 Doctor C
26 Doctor D
495 Doctor E
I have three collections in CMS:
ID Title of Collection
12 IM Collection
43 UR Collection
9 EC Collection
The following code retrieves the content for the collection which is working for me:
ContentManager contentManager = new ContentManager();
ContentCollectionCriteria criteria = new ContentCollectionCriteria(ContentProperty.Id, EkEnumeration.OrderByDirection.Ascending);
criteria.AddFilter(Convert.ToInt64(ddlCollection.SelectedValue));
List<ContentData> contentList = contentManager.GetList(criteria);
I will be including the following variable:
iPName (int) = the provider ID
sColl (List<string>) = The collection(s) the provider should go in
How can I code a recursive function for each provider, which will take the iPName, remove from any collection the provider exist and use the sCol to add the provider to the collection(s).
回答1:
Since you want to modify the collections, you'll want to take a look at the Collection specific APIs
The manager class is found inside the Ektron.Cms.Framework.Organization
namespace.
The basic idea is:
- Get a mapping between providers and each collection they are in
- Given
iPName
, get a list of Collections this provider is currently in - Compare the list from #2 to
sColl
(e.g. take the difference) - Any collections that don't currently contain the provider but should, add it
- Any collections that do currently contain the provider but shouldn't, delete it
Here's some rough code to get you started (untested)
//this is your existing code, wrapped into a function
List<ContentData> GetCollectionContent(long collectionID)
{
var contentManager = new ContentManager();
var criteria = new ContentCollectionCriteria(ContentProperty.Id, EkEnumeration.OrderByDirection.Ascending);
criteria.AddFilter(collectionID);
return contentManager.GetList(criteria);
}
//builds the mapping from step #1 above
Dictionary<ContentData, List<ContentCollectionData>> BuildCollectionMapping()
{
//get all the collections in the system (using a new, "default" criteria object)
var collectionManager = new CollectionManager();
var allCollections = collectionManager.GetList(new CollectionCriteria());
//build the mapping, associate a content item with each collection it is in
var mapping = new Dictionary<ContentData, List<ContentCollectionData>>();
foreach (var collection in allCollections)
{
var contentItems = GetCollectionContent(collection.Id);
foreach (var contentItem in contentItems)
{
if (!mapping.ContainsKey(contentItem))
{
mapping.Add(contentItem, new List<ContentCollectionData>());
}
mapping[contentItem].Add(collection);
}
}
return mapping;
}
//steps #2-3 from above, using the variables you defined
void Reconcile(long iPName, List<string> sColl)
{
var mapping = BuildCollectionMapping();
if (mapping.Keys.Any(content => content.Id == iPName))
{
var collections = mapping.Single(kvp => kvp.Key.Id == iPName).Value;
var collectionTitles = collections.Select(c => c.Title);
//these are the names of collections to which this content item must be added
var toAdd = sColl.Except(collectionTitles);
//these are the names of collections from which the content item must be deleted
var toDelete = collectionTitles.Except(sColl);
}
}
I'll leave it up to you to fill in the details of #4-5.
As a slight aside, I want to point out that IDs in Ektron should always be represented as long (your example above iPName
is int
).
We have just modified our environment such that content IDs are now being generated in the 64-bit range (e.g. 53687091658
) and we've run into a few cases where sloppy parsing to int
is resulting in runtime errors. The sample code I've provided uses long.
来源:https://stackoverflow.com/questions/34314732/how-to-remove-content-from-collection-and-add-it-to-another