Project.ReadProject 方法
取得指定之 Project Server 資料庫中指定的專案資料。
命名空間: WebSvcProject
組件: ProjectServerServices (在 ProjectServerServices.dll 中)
語法
'宣告
<SoapDocumentMethodAttribute("https://schemas.microsoft.com/office/project/server/webservices/Project/ReadProject", RequestNamespace := "https://schemas.microsoft.com/office/project/server/webservices/Project/", _
ResponseNamespace := "https://schemas.microsoft.com/office/project/server/webservices/Project/", _
Use := SoapBindingUse.Literal, ParameterStyle := SoapParameterStyle.Wrapped)> _
Public Function ReadProject ( _
projectUid As Guid, _
dataStore As DataStoreEnum _
) As ProjectDataSet
'用途
Dim instance As Project
Dim projectUid As Guid
Dim dataStore As DataStoreEnum
Dim returnValue As ProjectDataSet
returnValue = instance.ReadProject(projectUid, _
dataStore)
[SoapDocumentMethodAttribute("https://schemas.microsoft.com/office/project/server/webservices/Project/ReadProject", RequestNamespace = "https://schemas.microsoft.com/office/project/server/webservices/Project/",
ResponseNamespace = "https://schemas.microsoft.com/office/project/server/webservices/Project/",
Use = SoapBindingUse.Literal, ParameterStyle = SoapParameterStyle.Wrapped)]
public ProjectDataSet ReadProject(
Guid projectUid,
DataStoreEnum dataStore
)
參數
projectUid
類型:System.Guid專案的 GUID。
dataStore
類型:WebSvcProject.DataStoreEnum指定的資料庫的專案資料是位 (草稿、 發佈、 或封存)。
傳回值
類型:WebSvcProject.ProjectDataSet
包含完整的資料之指定的專案和專案內的實體。
備註
ProjectDataSet.ProjectResourceRow中傳回ProjectDataSet可能是企業資源, RES_IS_ENTERPRISE_RESOURCE所指示。如果是企業資源,此表格中的資料可能不會反映在企業級資源的目前狀態。資源新增至專案時,可能從企業內容複製屬性。如果稍後變更的企業資源 enterprise 屬性,其可能不完全反映在此列中的資料。同樣地,在此列所做的變更不會對企業內容,並可能會覆寫,如果資源內容會從企業資料重新整理。
Project Server 權限
權限 |
描述 |
---|---|
可讓使用者開啟專案。類別權限。 |
|
可讓使用者在載入企業通用範本。 |
範例
WCF 的範例: ReadMyProjects範例會執行下列動作:
取得目前使用者的 GUID。
使用ReadProjectStatus讀取所有使用者,可以看見的專案的清單。
使用ReadProject讀取清單中,每個專案。
如果專案擁有者符合目前的使用者:
將專案列複製到具有相同的結構描述建立ReadProjectStatusProjectDataSet 。
將專案列複製到第二個ProjectDataSet具有完整的結構描述。
將選取的任務資料中專案新增至TaskDataTable。
將每個輸出ProjectDataSet寫入至 XML 檔案,如結構描述的比較。
例如輸出的例外狀況處理常式中,請參閱 WCF 區段Project Server Error Codes的程式碼範例。
秘訣 |
---|
如果有大量讀取的專案,則報表資料庫的查詢可以更有效率。或者,PSI 延伸模組可以執行所有ReadProjectStatus及ReadProject的伺服器上,來電動作,並傳回剛最終ProjectDataSet。 |
如需使用Microsoft Visual Studio 2010專案中的程式碼範例及建立 app.config 檔案的 WCF 端點的組態資訊,請參閱 < Prerequisites for WCF-Based Code Samples。
using System;
using System.Text;
using System.ServiceModel;
using System.Xml;
using PSLibrary = Microsoft.Office.Project.Server.Library;
namespace Microsoft.SDK.Project.Samples.ReadMyProjects
{
class Program
{
private const string ENDPOINT_PROJECT = "basicHttp_Project";
private const string ENDPOINT_RESOURCE = "basicHttp_Resource";
// Change the output directory for your computer.
private const string OUTPUT_FILES = @"C:\Project\Samples\Output\";
private const string XML_FILE = "MyProjects.xml";
private const string XML_FILE2 = "MyProjects2.xml";
private static SvcProject.ProjectClient projectClient;
private static SvcResource.ResourceClient resourceClient;
static void Main(string[] args)
{
string outFilePath = OUTPUT_FILES + XML_FILE;
string outFilePath2 = OUTPUT_FILES + XML_FILE2;
try
{
ConfigClientEndpoints(ENDPOINT_PROJECT);
ConfigClientEndpoints(ENDPOINT_RESOURCE);
Guid myUid = resourceClient.GetCurrentUserUid();
Console.WriteLine("My GUID: {0}", myUid.ToString());
// Get the list of all projects visible to the user.
SvcProject.ProjectDataSet projectDs = projectClient.ReadProjectStatus(
Guid.Empty, SvcProject.DataStoreEnum.WorkingStore,
string.Empty, (int)PSLibrary.Project.ProjectType.Project);
SvcProject.ProjectDataSet tempProjDs = null;
// Create an empty ProjectDataSet for projects the user owns.
// By cloning the projectDs object, you get the same schema
// that is created by ReadProjectStatus.
SvcProject.ProjectDataSet myProjectsDs =
(SvcProject.ProjectDataSet)projectDs.Clone();
// Create an empty ProjectDataSet that contains the complete schema.
SvcProject.ProjectDataSet myProjectsDs2 = new SvcProject.ProjectDataSet();
Console.WriteLine("Projects I own:");
for (int i = 0; i < projectDs.Project.Count; i++)
{
tempProjDs = projectClient.ReadProject(projectDs.Project[i].PROJ_UID,
SvcProject.DataStoreEnum.WorkingStore);
if (tempProjDs.Project[0].ProjectOwnerID == myUid)
{
Console.WriteLine("\t" + tempProjDs.Project[0].PROJ_NAME);
myProjectsDs.Project.ImportRow(
(SvcProject.ProjectDataSet.ProjectRow)tempProjDs.Project[0]);
myProjectsDs2.Project.ImportRow(
(SvcProject.ProjectDataSet.ProjectRow)tempProjDs.Project[0]);
// You can add task data to either ProjectDataSet. However,
// only myProjectsDs2 contains the complete Project table schema.
for (int t = 0; t < tempProjDs.Task.Count; t++)
{
// To get all of the task data, use the following statement
// instead of adding a new task row with specific fields.
//myProjectsDs2.Task.ImportRow(
// (SvcProject.ProjectDataSet.TaskRow)tempProjDs.Task[t]);
// Add specific data in a new task row.
SvcProject.ProjectDataSet.TaskRow taskRow =
myProjectsDs2.Task.NewTaskRow();
// If you comment-out the following line, you get a constraint error.
taskRow.PROJ_UID = tempProjDs.Task[t].PROJ_UID;
taskRow.TASK_UID = tempProjDs.Task[t].TASK_UID;
taskRow.TASK_NAME = tempProjDs.Task[t].TASK_NAME;
taskRow.TASK_IS_MANUAL = tempProjDs.Task[t].TASK_IS_MANUAL;
myProjectsDs2.Task.AddTaskRow(taskRow);
}
}
}
Console.WriteLine(
"\nXML output of myProjectsDs and myProjectDs2:\n\t{0}",
outFilePath);
// Write both XML files for comparison of the ProjectDataSet schemas.
myProjectsDs.WriteXml(outFilePath);
myProjectsDs2.WriteXml(outFilePath2);
}
catch (FaultException fault)
{
// Use the WCF FaultException, because the ASMX SoapException does not
// exist in a WCF-based application.
WriteFaultOutput(fault);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.Write("\nPress any key to exit... ");
Console.ReadKey(true);
}
// Extract a PSClientError object from the WCF FaultException object, and
// then display the exception details and each error in the PSClientError stack.
private static void WriteFaultOutput(FaultException fault)
{
string errAttributeName;
string errAttribute;
string errOut;
string errMess = "".PadRight(30, '=') + "\r\n"
+ "Error details: " + "\r\n";
PSLibrary.PSClientError error = Helpers.GetPSClientError(fault, out errOut);
errMess += errOut;
PSLibrary.PSErrorInfo[] errors = error.GetAllErrors();
PSLibrary.PSErrorInfo thisError;
for (int i = 0; i < errors.Length; i++)
{
thisError = errors[i];
errMess += "\r\n".PadRight(30, '=') + "\r\nPSClientError output:\r\n";
errMess += thisError.ErrId.ToString() + "\n";
for (int j = 0; j < thisError.ErrorAttributes.Length; j++)
{
errAttributeName = thisError.ErrorAttributeNames()[j];
errAttribute = thisError.ErrorAttributes[j];
errMess += "\r\n\t" + errAttributeName
+ ": " + errAttribute;
}
}
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(errMess);
Console.ResetColor();
}
// Use the endpoints defined in app.config to configure the client.
public static void ConfigClientEndpoints(string endpt)
{
if (endpt == ENDPOINT_PROJECT)
projectClient = new SvcProject.ProjectClient(endpt);
else if (endpt == ENDPOINT_RESOURCE)
resourceClient = new SvcResource.ResourceClient(endpt);
}
}
// Helper method: GetPSClientError.
class Helpers
{
/// <summary>
/// Extract a PSClientError object from the ServiceModel.FaultException,
/// for use in output of the GetPSClientError stack of errors.
/// </summary>
/// <param name="e"></param>
/// <param name="errOut">Shows that FaultException has more information
/// about the errors than PSClientError has. FaultException can also contain
/// other types of errors, such as failure to connect to the server.</param>
/// <returns>PSClientError object, for enumerating errors.</returns>
public static PSLibrary.PSClientError GetPSClientError(FaultException e,
out string errOut)
{
const string PREFIX = "GetPSClientError() returns null: ";
errOut = string.Empty;
PSLibrary.PSClientError psClientError = null;
if (e == null)
{
errOut = PREFIX + "Null parameter (FaultException e) passed in.";
psClientError = null;
}
else
{
// Get a ServiceModel.MessageFault object.
var messageFault = e.CreateMessageFault();
if (messageFault.HasDetail)
{
using (var xmlReader = messageFault.GetReaderAtDetailContents())
{
var xml = new XmlDocument();
xml.Load(xmlReader);
var serverExecutionFault = xml["ServerExecutionFault"];
if (serverExecutionFault != null)
{
var exceptionDetails = serverExecutionFault["ExceptionDetails"];
if (exceptionDetails != null)
{
try
{
errOut = exceptionDetails.InnerXml + "\r\n";
psClientError =
new PSLibrary.PSClientError(exceptionDetails.InnerXml);
}
catch (InvalidOperationException ex)
{
errOut = PREFIX + "Unable to convert fault exception info ";
errOut += "a valid Project Server error message. Message: \n\t";
errOut += ex.Message;
psClientError = null;
}
}
else
{
errOut = PREFIX
+ "The FaultException e is a ServerExecutionFault, "
+ "but does not have ExceptionDetails.";
}
}
else
{
errOut = PREFIX
+ "The FaultException e is not a ServerExecutionFault.";
}
}
}
else // No detail in the MessageFault.
{
errOut = PREFIX + "The FaultException e does not have any detail.";
}
}
errOut += "\r\n" + e.ToString() + "\r\n";
return psClientError;
}
}
}
的以 ASMX 範例: 下列範例會建立範例專案 」、 「 讀取其備份] 中,與 「 傾印主控台的內容。
如需執行此程式碼範例的重要資訊,請參閱 < Prerequisites for Reference Code Samples。
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Data;
using System.Web.Services.Protocols;
using System.Threading;
using PSLibrary = Microsoft.Office.Project.Server.Library;
namespace Microsoft.SDK.Project.Samples.ReadProject
{
class Program
{
[STAThread]
static void Main()
{
try
{
#region Setup
const string PROJECT_SERVER_URI = "https://ServerName/ProjectServerName/";
const string PROJECT_SERVICE_PATH = "_vti_bin/psi/project.asmx";
const string RESOURCE_SERVICE_PATH = "_vti_bin/psi/resource.asmx";
const string RESOURCEPLAN_SERVICE_PATH = "_vti_bin/psi/resource.asmx";
const string QUEUESYSTEM_SERVICE_PATH = "_vti_bin/psi/queuesystem.asmx";
// Set up the web service objects.
SvcProject.Project projectSvc = new SvcProject.Project();
projectSvc.Url = PROJECT_SERVER_URI + PROJECT_SERVICE_PATH;
projectSvc.UseDefaultCredentials = true;
SvcResource.Resource resourceSvc = new SvcResource.Resource();
resourceSvc.Url = PROJECT_SERVER_URI + RESOURCE_SERVICE_PATH;
resourceSvc.UseDefaultCredentials = true;
SvcResourcePlan.ResourcePlan resourcePlanSvc = new SvcResourcePlan.ResourcePlan();
resourcePlanSvc.Url = PROJECT_SERVER_URI + RESOURCEPLAN_SERVICE_PATH;
resourcePlanSvc.UseDefaultCredentials = true;
SvcQueueSystem.QueueSystem q = new SvcQueueSystem.QueueSystem();
q.Url = PROJECT_SERVER_URI + QUEUESYSTEM_SERVICE_PATH;
q.UseDefaultCredentials = true;
// Create a sample project.
Console.WriteLine("Creating the project");
Guid projectId = CreateSampleProject(projectSvc, q, resourceSvc);
#endregion
#region Read Sample Project
Console.WriteLine("Reading in the project");
SvcProject.ProjectDataSet projectDs = projectSvc.ReadProject(projectId, SvcProject.DataStoreEnum.WorkingStore);
#endregion
#region Write out project
// Write the project tables to the console.
Console.WriteLine("And here it is:");
WriteTablesToConsole(projectDs.Tables);
#endregion
}
#region Exception Handling and Final
catch (SoapException ex)
{
PSLibrary.PSClientError error = new PSLibrary.PSClientError(ex);
PSLibrary.PSErrorInfo[] errors = error.GetAllErrors();
string errMess = "==============================\r\nError: \r\n";
for (int i = 0; i < errors.Length; i++)
{
errMess += "\n" + ex.Message.ToString() + "\r\n";
errMess += "".PadRight(30, '=') + "\r\nPSCLientError Output:\r\n \r\n";
errMess += errors[i].ErrId.ToString() + "\n";
for (int j = 0; j < errors[i].ErrorAttributes.Length; j++)
{
errMess += "\r\n\t" + errors[i].ErrorAttributeNames()[j] + ": " + errors[i].ErrorAttributes[j];
}
errMess += "\r\n".PadRight(30, '=');
}
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(errMess);
}
catch (WebException ex)
{
string errMess = ex.Message.ToString() +
"\n\nLog on, or check the Project Server Queuing Service";
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Error: " + errMess);
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Error: " + ex.Message);
}
finally
{
Console.ResetColor();
Console.WriteLine("\r\n\r\nPress any key...");
Console.ReadKey();
}
#endregion
}
// Wait for the job to finish.
// Outputs job status to the console.
static private void WaitForQueue(SvcQueueSystem.QueueSystem q, Guid jobId)
{
SvcQueueSystem.JobState jobState;
const int QUEUE_WAIT_TIME = 1; // one second
bool jobDone = false;
string xmlError = string.Empty;
int wait = 0;
// Wait for the project to get through the queue.
// Get the estimated wait time in seconds.
wait = q.GetJobWaitTime(jobId);
// Wait for it.
Console.Write("Waiting on queue. Estimate: {0} seconds.\r\n ", wait);
// Wait until it is finished.
do
{
// Get the job state.
jobState = q.GetJobCompletionState(jobId, out xmlError);
if (jobState == SvcQueueSystem.JobState.Success)
{
jobDone = true;
}
else
{
if (jobState == SvcQueueSystem.JobState.Unknown
|| jobState == SvcQueueSystem.JobState.Failed
|| jobState == SvcQueueSystem.JobState.FailedNotBlocking
|| jobState == SvcQueueSystem.JobState.CorrelationBlocked
|| jobState == SvcQueueSystem.JobState.Canceled)
{
// If the job failed, error out.
throw (new ApplicationException("Queue request " + jobState + " for Job ID " + jobId + ".\r\n" + xmlError));
}
else
{
//Console.WriteLine("Job State: " + jobState + " for Job ID: " + jobId);
Console.Write("~");
Thread.Sleep(QUEUE_WAIT_TIME * 1000);
}
}
}
while (!jobDone);
Console.Write("\r\n");
}
static private Guid CreateSampleProject(SvcProject.Project projectSvc, SvcQueueSystem.QueueSystem q, SvcResource.Resource resourceSvc)
{
SvcProject.ProjectDataSet projectDs = new SvcProject.ProjectDataSet();
Guid jobId;
Guid sessionUid = Guid.NewGuid();
const string SESSION_DESC = "Test Utility";
// Create the project.
SvcProject.ProjectDataSet.ProjectRow projectRow = projectDs.Project.NewProjectRow();
Guid projectId = Guid.NewGuid();
projectRow.PROJ_UID =projectId;
projectRow.PROJ_NAME = "Its a wonderful project at " +
DateTime.Now.ToShortDateString().Replace("/", "") + " " +
DateTime.Now.ToShortTimeString().Replace(":", "") +" "+
DateTime.Now.Millisecond.ToString() ;
projectRow.PROJ_TYPE = (int)PSLibrary.Project.ProjectType.Project;
projectDs.Project.AddProjectRow(projectRow);
// Add some tasks.
SvcProject.ProjectDataSet.TaskRow taskOne = projectDs.Task.NewTaskRow();
taskOne.PROJ_UID = projectId;
taskOne.TASK_UID = Guid.NewGuid();
taskOne.TASK_NAME = "Task One";
taskOne.TASK_DUR_FMT = (int)PSLibrary.Task.DurationFormat.Hour;
taskOne.TASK_DUR = 10*60*8*3; //Three eight hour days
taskOne.TASK_START_DATE = System.DateTime.Now.AddDays(1);
projectDs.Task.AddTaskRow(taskOne);
SvcProject.ProjectDataSet.TaskRow taskTwo = projectDs.Task.NewTaskRow();
taskTwo.PROJ_UID = projectId;
taskTwo.TASK_UID = Guid.NewGuid();
taskTwo.TASK_NAME = "Task Two";
taskTwo.TASK_DUR = 10 * 60 * 6; // 6 hours
taskTwo.TASK_DUR_FMT = (int)PSLibrary.Task.DurationFormat.EHour; // Duration Estimate and shoudl be displayed in hours
projectDs.Task.AddTaskRow(taskTwo);
// Make task two dependent on task one.
SvcProject.ProjectDataSet.DependencyRow dependency = projectDs.Dependency.NewDependencyRow();
dependency.LINK_UID = Guid.NewGuid();
dependency.PROJ_UID = projectId;
dependency.LINK_PRED_UID = taskOne.TASK_UID;
dependency.LINK_SUCC_UID = taskTwo.TASK_UID;
dependency.LINK_TYPE = 1; //Finish to Start
dependency.LINK_LAG_FMT =(int) PSLibrary.Task.DurationFormat.Hour;
dependency.LINK_LAG = 0;
projectDs.Dependency.AddDependencyRow(dependency);
// Add a summary task.
SvcProject.ProjectDataSet.TaskRow taskOthers = projectDs.Task.NewTaskRow();
taskOthers.PROJ_UID = projectId;
taskOthers.TASK_UID = Guid.NewGuid();
taskOthers.TASK_NAME = "Related Tasks";
projectDs.Task.AddTaskRow(taskOthers);
// Add some subtasks.
SvcProject.ProjectDataSet.TaskRow taskThree = projectDs.Task.NewTaskRow();
taskThree.PROJ_UID = projectId;
taskThree.TASK_UID = Guid.NewGuid();
taskThree.TASK_NAME = "Task Three";
taskThree.TASK_PARENT_UID = taskOthers.TASK_UID;
taskThree.TASK_OUTLINE_LEVEL = 2;
taskThree.TASK_DUR = 9600; //Two days
taskThree.TASK_DUR_FMT = (int)PSLibrary.Task.DurationFormat.Day;
projectDs.Task.AddTaskRow(taskThree);
SvcProject.ProjectDataSet.TaskRow taskFour = projectDs.Task.NewTaskRow();
taskFour.PROJ_UID = projectId;
taskFour.TASK_UID = Guid.NewGuid();
taskFour.TASK_NAME = "Task Four";
taskFour.TASK_PARENT_UID = taskOthers.TASK_UID;
taskFour.TASK_DUR = 4800; //One day
taskFour.TASK_DUR_FMT = (int)PSLibrary.Task.DurationFormat.Hour;
taskFour.TASK_OUTLINE_LEVEL = 2;
projectDs.Task.AddTaskRow(taskFour);
// Make task four dependent on task three.
dependency = projectDs.Dependency.NewDependencyRow();
dependency.LINK_UID = Guid.NewGuid();
dependency.PROJ_UID = projectId;
dependency.LINK_PRED_UID = taskThree.TASK_UID;
dependency.LINK_SUCC_UID = taskFour.TASK_UID;
dependency.LINK_TYPE = 1; //Finish to Start
dependency.LINK_LAG = 0;
projectDs.Dependency.AddDependencyRow(dependency);
// Make others task dependent on task two.
dependency = projectDs.Dependency.NewDependencyRow();
dependency.LINK_UID = Guid.NewGuid();
dependency.PROJ_UID = projectId;
dependency.LINK_PRED_UID = taskTwo.TASK_UID;
dependency.LINK_SUCC_UID = taskOthers.TASK_UID;
dependency.LINK_TYPE = 1; //Finish to Start
dependency.LINK_LAG = 0;
projectDs.Dependency.AddDependencyRow(dependency);
//Add some local project resources.
SvcProject.ProjectDataSet.ProjectResourceRow resourceOne = projectDs.ProjectResource.NewProjectResourceRow();
resourceOne.PROJ_UID = projectId;
resourceOne.RES_UID = Guid.NewGuid();
resourceOne.RES_NAME = "Brynja Sigrídur Blomsterberg";
resourceOne.RES_INITIALS = "BSB";
projectDs.ProjectResource.AddProjectResourceRow(resourceOne);
CreateAssignment(projectDs, taskOne.TASK_UID, resourceOne.RES_UID);
CreateAssignment(projectDs, taskTwo.TASK_UID, resourceOne.RES_UID);
SvcProject.ProjectDataSet.ProjectResourceRow resourceTwo = projectDs.ProjectResource.NewProjectResourceRow();
resourceTwo.PROJ_UID = projectId;
resourceTwo.RES_UID = Guid.NewGuid();
resourceTwo.RES_NAME = "Ioannis Xylaras";
resourceTwo.RES_INITIALS = "IX";
projectDs.ProjectResource.AddProjectResourceRow(resourceTwo);
CreateAssignment(projectDs, taskOne.TASK_UID, resourceTwo.RES_UID);
CreateAssignment(projectDs, taskTwo.TASK_UID, resourceTwo.RES_UID);
CreateAssignment(projectDs, taskThree.TASK_UID, resourceTwo.RES_UID);
CreateAssignment(projectDs, taskFour.TASK_UID, resourceTwo.RES_UID);
// Save the project to the database.
jobId = Guid.NewGuid();
projectSvc.QueueCreateProject(jobId, projectDs, false);
WaitForQueue(q, jobId);
// Add or retrieve an enterprise resource.
SvcResource.ResourceDataSet resourceDs = EnsureEnterpriseResource(resourceSvc);
// Add the resource to the team.
SvcProject.ProjectTeamDataSet projectTeamDs = new SvcProject.ProjectTeamDataSet();
ProjectTeamAddResource(projectTeamDs, projectId, resourceDs.Resources[0].RES_UID, resourceDs.Resources[0].RES_UID);
projectSvc.CheckOutProject(projectId, sessionUid, SESSION_DESC);
// Save the team.
jobId = Guid.NewGuid();
projectSvc.QueueUpdateProjectTeam(jobId, sessionUid, projectId, projectTeamDs);
WaitForQueue(q, jobId);
// Read the project back in to get the updated team.
//projectDs = projectSvc.ReadProject(projectId, SvcProject.DataStoreEnum.WorkingStore);
projectDs = new SvcProject.ProjectDataSet();
// Add the resource to an assignment.
CreateAssignment(projectDs, taskOne.TASK_UID, resourceDs.Resources[0].RES_UID,projectId);
// Save the enterprise assignment.
jobId = Guid.NewGuid();
// Get only the added rows.
projectDs = (SvcProject.ProjectDataSet) projectDs.GetChanges(DataRowState.Added);
projectSvc.QueueAddToProject(jobId, sessionUid, projectDs, false);
WaitForQueue(q,jobId);
// Check in the project.
jobId = Guid.NewGuid();
projectSvc.QueueCheckInProject(jobId, projectId, false, sessionUid, SESSION_DESC);
WaitForQueue(q, jobId);
return projectRow.PROJ_UID;
}
// A helper function for CreateSampleProject.
// Makes a simple assignment.
private static void CreateAssignment(SvcProject.ProjectDataSet projectDs, Guid taskGuid, Guid resourceGuid)
{
CreateAssignment(projectDs, taskGuid, resourceGuid, projectDs.Project[0].PROJ_UID);
}
private static void CreateAssignment(SvcProject.ProjectDataSet projectDs, Guid taskGuid, Guid resourceGuid, Guid projectId)
{
SvcProject.ProjectDataSet.AssignmentRow assnRow = projectDs.Assignment.NewAssignmentRow();
assnRow.PROJ_UID = projectId;
assnRow.ASSN_UID = Guid.NewGuid();
assnRow.TASK_UID = taskGuid;
assnRow.RES_UID = resourceGuid;
projectDs.Assignment.AddAssignmentRow(assnRow);
}
// A helper function for Create Project.
// Adds an enterprise resource to the project
// so that is can be used on the project.
public static void ProjectTeamAddResource(SvcProject.ProjectTeamDataSet projTeamDataSet, Guid projGuid, Guid resGuid, Guid newResGuid)
{
SvcProject.ProjectTeamDataSet.ProjectTeamRow projTeamRow = projTeamDataSet.ProjectTeam.NewProjectTeamRow();
projTeamRow.PROJ_UID = projGuid;
projTeamRow.RES_UID = resGuid;
projTeamRow.NEW_RES_UID = newResGuid;
projTeamDataSet.ProjectTeam.AddProjectTeamRow(projTeamRow);
}
// A helper function for Create Project.
// Creates or retrieves an enterprise resource.
private static SvcResource.ResourceDataSet EnsureEnterpriseResource(SvcResource.Resource resourceSvc)
{
const string RES_NAME = "Lertchai Treetawatchaiwong";
SvcResource.ResourceDataSet resourceDs = new SvcResource.ResourceDataSet();
PSLibrary.Filter resourceFilter = new Microsoft.Office.Project.Server.Library.Filter();
resourceFilter.FilterTableName = resourceDs.Resources.TableName;
resourceFilter.Fields.Add(new PSLibrary.Filter.Field(resourceDs.Resources.TableName, resourceDs.Resources.RES_UIDColumn.ColumnName, PSLibrary.Filter.SortOrderTypeEnum.None));
resourceFilter.Fields.Add(new PSLibrary.Filter.Field(resourceDs.Resources.TableName, resourceDs.Resources.RES_NAMEColumn.ColumnName, PSLibrary.Filter.SortOrderTypeEnum.None));
resourceFilter.Fields.Add(new PSLibrary.Filter.Field(resourceDs.Resources.TableName, resourceDs.Resources.RES_INITIALSColumn.ColumnName, PSLibrary.Filter.SortOrderTypeEnum.None));
resourceFilter.Fields.Add(new PSLibrary.Filter.Field(resourceDs.Resources.TableName, resourceDs.Resources.RES_TYPEColumn.ColumnName, PSLibrary.Filter.SortOrderTypeEnum.None));
PSLibrary.Filter.FieldOperator existingResource = new PSLibrary.Filter.FieldOperator(PSLibrary.Filter.FieldOperationType.Equal, resourceDs.Resources.RES_NAMEColumn.ColumnName, RES_NAME);
resourceFilter.Criteria = existingResource;
resourceDs = resourceSvc.ReadResources(resourceFilter.GetXml(), false);
if (resourceDs.Resources.Count >= 1)
{
return resourceDs;
}
else
{
resourceDs = new SvcResource.ResourceDataSet();
SvcResource.ResourceDataSet.ResourcesRow resourceRow = resourceDs.Resources.NewResourcesRow();
resourceRow.RES_UID = Guid.NewGuid();
resourceRow.RES_NAME = RES_NAME;
resourceRow.RES_INITIALS = "LT";
resourceDs.Resources.AddResourcesRow(resourceRow);
resourceSvc.CreateResources(resourceDs, false, true);
return resourceDs;
}
}
// Write all contents of a table collection to the console.
private static void WriteTablesToConsole(System.Data.DataTableCollection theTables)
{
Console.ForegroundColor = ConsoleColor.DarkGreen;
foreach (System.Data.DataTable table in theTables)
{
int[] columnWidths = new int[table.Columns.Count];
int tableWidth = 0;
string dataString;
Console.WriteLine("Table: " + table.TableName);
// Write out the column names and get their spacing.
StringBuilder tableRow = new StringBuilder();
for (int i = 0; i < table.Columns.Count; i++)
{
columnWidths[i] = GetColumnWidth(table.Columns[i]);
tableRow.Append(table.Columns[i].ColumnName.PadRight(columnWidths[i]));
tableWidth += columnWidths[i];
}
// Add a space so that it will not wrap.
tableWidth += 1;
// make the console as wide as the widest table
Console.BufferWidth = (Console.BufferWidth > tableWidth ? Console.BufferWidth : tableWidth);
tableRow.Append("\r\n");
Console.Write(tableRow.ToString());
// Write out the data.
foreach (DataRow row in table.Rows)
{
tableRow = new StringBuilder();
for (int i = 0; i < table.Columns.Count; i++)
{
dataString = row[i].ToString();
// Truncate output, if it is wider than
// the desired column width.
if (dataString.Length >= columnWidths[i])
{
dataString = dataString.Substring(0, columnWidths[i] - 1);
}
// Add the output to the stringbuilder and pad right to fill
// up to the column width.
tableRow.Append(dataString.PadRight(columnWidths[i]));
}
tableRow.Append("\r\n");
Console.Write(tableRow.ToString());
}
Console.Write("\r\n".PadLeft(tableWidth, '-'));
}
Console.ResetColor();
}
// A helper function for WriteTablesToConsole.
private static int GetColumnWidth(DataColumn column)
{
// Note: May not handle byte[]data types well.
const int MAX_COL_WIDTH = 40;
int dataWidth = 0;
//Return 12 for numbers, 30 for dates, and string width for strings.
switch (column.DataType.UnderlyingSystemType.ToString())
{
case "System.Boolean":
case "System.Byte":
case "System.Byte[]":
case "System.Char":
case "System.Decimal":
case "System.Double":
case "System.Int16":
case "System.Int32":
case "System.Int64":
case "System.SByte":
case "System.Single":
case "System.UInt16":
case "System.UInt32":
case "System.UInt64":
dataWidth = 12;
break;
case "System.DateTime":
case "System.TimeSpan":
dataWidth = 30;
break;
case "System.Guid":
dataWidth = 37;
break;
case "System.String":
// If it has a maxlength, use it
if (column.MaxLength > 0)
{
dataWidth = column.MaxLength;
}
else
{
// Otherwise use the max col width.
dataWidth = MAX_COL_WIDTH;
}
break;
default:
dataWidth = column.ColumnName.Length;
break;
}
// Truncate, if over the max length.
if (dataWidth > MAX_COL_WIDTH)
{
dataWidth = MAX_COL_WIDTH;
}
// Always be at least as wide as the colum name.
return (column.ColumnName.Length > (dataWidth) ? column.ColumnName.Length + 1 : dataWidth);
}
}
}