[英]What's the most efficient way to get only the final row of a SQL table using EF4?
[英]What's the most efficient way to get all attachments from any row in every sheet using Smartsheet API?
最重要的是,有没有什么方法可以获取附件列表,而无需深入到行级别,而不必进行 2 次调用以获取attachment id
,然后再进行 1 次调用以获取附件?
我正在尝试编写一个脚本,该脚本使用 Smartsheet 的 API 从所有/特定工作表中获取所有需要的附件。 到目前为止,我有实现目标的代码,但它非常低效,因为它必须通过数千行检查 go 以查看是否有附件。 这两行代码都返回包含“附件”属性的对象或对象列表,但它始终为 null。
// get all sheet resources
PaginatedResult<Sheet> sheets = smartsheet.SheetResources.ListSheets(null, null, null);
var includeAttachments = new List<SheetLevelInclusion> { SheetLevelInclusion.ATTACHMENTS };
var sheet = smartsheet.SheetResources.GetSheet(sheetId, includeAttachments, null, null, null, null, null, null);
每个方法都有一个IEnumerable<SheetLevelInclusion>
参数,但我不确定如果可能的话如何利用它。
我将提供我的整个方法,为您提供更多背景信息。 我还包含了一个尚未实现的FilterSheets
方法。 我也愿意接受Python
回答。
private List<SMTPAttachment> GetAttachments(SmartsheetClient smartsheet)
{
var includeAttachments = new List<SheetLevelInclusion> { SheetLevelInclusion.ATTACHMENTS };
// get all sheet resources
PaginatedResult<Sheet> sheets = smartsheet.SheetResources.ListSheets(null, null, null);
// filter out sheets that don't have desired attachments
var filteredSheets = FilterSheets(sheets);
// initalize necessary objects to store data
var attachments = new List<SMTPAttachment>();
// for each sheet in sheets:
foreach (var tempSheet in filteredSheets)
{
var sheetId = (long)tempSheet.Id;
var sheet = smartsheet.SheetResources.GetSheet(sheetId, includeAttachments, null, null, null, null, null, null);
// for each row in sheet.Rows
foreach (Row row in sheet.Rows)
{
long rowId = (long)row.Id;
var paging = new PaginationParameters(true, 1, 1);
var smtpAttachment = new SMTPAttachment();
PaginatedResult<Attachment> updatedAttachment = smartsheet.SheetResources.RowResources.AttachmentResources.ListAttachments(
sheetId,
rowId,
paging
);
if (updatedAttachment.Data.Count != 0)
{
var attachmentInfo = updatedAttachment.Data.FirstOrDefault();
if (attachmentInfo != null)
{
// finally getting the attachment here
var attachment = smartsheet.SheetResources.AttachmentResources.GetAttachment(sheetId, (long)attachmentInfo.Id);
smtpAttachment.Attachment = attachment;
smtpAttachment.Name = attachment.Name;
smtpAttachment.Url = attachment.Url;
smtpAttachment.MimeType = attachment.MimeType;
attachments.Add(smtpAttachment);
Console.WriteLine("Attaching file : " + attachment.Name);
}
}
else
{
Console.WriteLine("No Data for row: " + rowId);
}
}
}
return attachments;
}
private List<Sheet> FilterSheets(PaginatedResult<Sheet> sheets)
{
/// TODO: implement filter code
var filteredSheets = sheets.Data.ToList().Where(sheet => sheet.Id == sheet.Id).ToList();
return filteredSheets;
}
更新:
我的原始答案(如下)假设除了有关附件的信息外,您还需要其他与工作表相关的数据。 如果这是您的情况,那么使用单个Get Sheet API 请求是最有效的方法,因为它允许您使用单个 API 调用来检索所有与工作表相关的数据以及有关工作表中附件的数据。
但是,如果您只需要有关指定工作表中附件的数据,您可能会考虑使用列出附件操作。 此操作返回有关工作表中存在的所有附件的信息,无论位置如何(即,工作表附件、行附件、工作表级别的讨论附件、行级别的讨论附件)。 使用List Attachment操作(如果您只需要与附件相关的数据而不需要任何其他工作表数据)比使用Get Sheet操作检索附件数据更有效,因为响应会小得多并且代码您需要编写以更简单地处理响应。 这是一些示例代码:
SmartsheetClient smartsheet = new SmartsheetBuilder()
.SetAccessToken("ADD_YOUR_ACCESS_TOKEN_HERE")
.Build();
var sheetId = (long) 3932034054809476;
// Omit pagination parameters
PaginatedResult<Attachment> attachments = smartsheet.SheetResources.AttachmentResources.ListAttachments(sheetId, null);
Console.WriteLine("Number of attachments found = " + attachments.TotalCount);
foreach(var attachment in attachments.Data) {
Console.WriteLine("Attachment name | ID | location: " + attachment.Name + " | " + attachment.Id + " | " + attachment.ParentType);
}
当针对我在原始答案(下方)中描述的工作表运行时,此代码会生成以下控制台 output:
请注意,无论您使用哪种 API 方法检索附件信息(获取工作表或列出附件),API 响应都将仅包含每个附件的元数据子集。 对于Get Sheet或List Attachments响应中的每个附件,您需要发出Get Attachment请求以检索有关附件的完整元数据集——包括可用于访问文件本身的url
属性。
原始答案:
可以通过发出单个Get Sheet请求(指定适当的SheetLevelInclusion
值)来获取有关工作表中包含的所有附件的信息——但您需要评估响应的 4 个独立部分以识别工作表中的所有附件。 这是因为有 4 个不同的地方可以添加附件:
例如,考虑 Smartsheet 中的一个工作表,其中包含以下 Smartsheet 屏幕截图中列出的 6 个附件,其中:
file6.txt
附加到工作表级别的讨论file5.txt
附加在 SHEET 级别file4.txt
附加到 ROW 级别的讨论(在第 1 行)file3.txt
和file2.txt
附加在 ROW 级别(在第 4 行)file1.txt
附加在 ROW 级别(在第 1 行)JSON 对此工作表的获取工作表请求的响应如下所示(为简洁起见进行了编辑,仅在响应中显示相关数据):
{
"id": 3932034054809476,
...
"columns": [
...
],
"rows": [
{
"id": 6933706290423684,
"rowNumber": 1,
...
"discussions": [
{
"id": 5173128113219460,
"title": "This is a discussion!",
"commentCount": 1,
"commentAttachments": [
{
"id": 1958653853755268,
"name": "file4.txt",
"attachmentType": "FILE",
...
}
],
...
}
],
"attachments": [
{
"id": 1061849918400388,
"name": "file1.txt",
"attachmentType": "FILE",
...
}
]
},
{
"id": 1304206756210564,
"rowNumber": 2,
...
},
{
"id": 770536852088708,
"rowNumber": 3,
...
},
{
"id": 7046650170566532,
"rowNumber": 4,
...
"attachments": [
{
"id": 7092080722634628,
"name": "file3.txt",
"attachmentType": "FILE",
...
},
{
"id": 2426000334972804,
"name": "file2.txt",
"attachmentType": "FILE",
...
]
}
],
"discussions": [
{
"id": 4967439377950596,
"title": "This is a comment on the sheet level.",
"commentCount": 1,
"commentAttachments": [
{
"id": 976830369687428,
"name": "file6.txt",
"attachmentType": "FILE",
...
}
],
...
}
],
"attachments": [
{
"id": 135383999375236,
"name": "file5.txt",
"attachmentType": "FILE",
...
}
]
}
这个 JSON 响应显示了存在于前面描述的不同位置的附件。
以下 C# 代码发出获取工作表请求(指定了适当的SheetLevelInclusion
值)以检索指定的工作表(包括有关工作表中任何位置存在的所有附件的信息)。 然后,它会查看 4 个位置中的每一个,并在找到附件时将 output 写入控制台。
SmartsheetClient smartsheet = new SmartsheetBuilder()
.SetAccessToken("ADD_YOUR_TOKEN_STRING_HERE")
.Build();
var sheetId = (long) 3932034054809476;
// Sheet inclusions must specify attachments AND discussions in order to get all attachments present within the sheet
// (i.e., attachments present on: SHEET object, ROW objects, DISCUSSION objects at the SHEET level, DISCUSSION objects at the ROW LEVEL)
var sheetLevelInclusion = new List<SheetLevelInclusion> { SheetLevelInclusion.ATTACHMENTS, SheetLevelInclusion.DISCUSSIONS };
Console.WriteLine("Loading sheet id: " + sheetId);
// Get the sheet.
var sheet = smartsheet.SheetResources.GetSheet(sheetId, sheetLevelInclusion, null, null, null, null, null, null);
Console.WriteLine("Loaded " + sheet.Rows.Count + " rows from sheet: " + sheet.Name);
Console.WriteLine("---------");
// 1- Attachments that exist on the SHEET object
if (sheet.Attachments != null) {
// iterate through all attachments found on SHEET object
foreach (var attachment in sheet.Attachments) {
Console.WriteLine("Attachment found (at SHEET-level): " + attachment.Name + " (attachment ID = " + attachment.Id + ")");
// Add logic to process attachment here.
}
}
Console.WriteLine("---------");
// 2- Attachments that exist on the DISCUSSION objects at the SHEET level
if (sheet.Discussions != null) {
// iterate through all discussion objects (at the sheet level), looking for attachments on each discussion.
foreach (var discussion in sheet.Discussions) {
if (discussion.CommentAttachments != null) {
foreach (var attachment in discussion.CommentAttachments) {
Console.WriteLine("Attachment found (on SHEET-level Discussion): " + attachment.Name + " (attachment ID = " + attachment.Id + ")");
// Add logic to process attachment here.
}
}
}
}
Console.WriteLine("---------");
// 3- Attachments that exist on ROW objects
foreach (var row in sheet.Rows) {
if (row.Attachments != null) {
// process attachments on the current row
foreach (var attachment in row.Attachments) {
Console.WriteLine("Attachment found (at ROW-level) on Row # " + row.RowNumber + ": " + attachment.Name + " (attachment ID = " + attachment.Id + ")");
// Add logic to process attachment here.
}
}
// 4- Attachments that exist on DISCUSSION objects at the ROW level
if (row.Discussions != null) {
// iterate through all discussion objects (on the current row), looking for attachments on each discussion.
foreach (var discussion in row.Discussions) {
if (discussion.CommentAttachments != null) {
foreach (var attachment in discussion.CommentAttachments) {
Console.WriteLine("Attachment found (on ROW-level Discussion) in Row # " + row.RowNumber + ": " + attachment.Name + " (attachment ID = " + attachment.Id + ")");
// Add logic to process attachment here.
}
}
}
}
}
Console.WriteLine("---------");
针对我之前描述的工作表运行时,此代码会生成以下控制台 output:
希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.