首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LINQ-To-Sharepoint单个列表的多种内容类型

LINQ-To-Sharepoint单个列表的多种内容类型
EN

Stack Overflow用户
提问于 2012-02-22 06:38:31
回答 1查看 2.4K关注 0票数 1

我使用SPMetal为我的sharepoint站点生成实体类,当一个列表有多个内容类型时,我不确定最佳实践是什么。例如,我有一个包含2个内容类型的任务列表,并且我通过SPMetal的配置文件来定义它们。这是我的定义。

代码语言:javascript
复制
<List Member="Tasks" Name="Tasks">
    <ContentType Class="LegalReview" Name="LegalReviewContent"/>      
    <ContentType Class="Approval" Name="ApprovalContent"/>      
</List>

这似乎工作得很好,因为生成的对象确实继承自WorkflowTask,但是为数据上下文生成的类型是一个WorkflowTask列表。因此,当我执行查询时,我会返回一个WorkflowTask对象,而不是LegalReview或Approval对象。如何让它返回正确类型的对象?

代码语言:javascript
复制
[Microsoft.SharePoint.Linq.ListAttribute(Name="Tasks")]
public Microsoft.SharePoint.Linq.EntityList<WorkflowTask> Tasks {
    get {
        return this.GetList<WorkflowTask>("Tasks");
    }
}

最新消息谢谢你给我回复。我不确定如何根据SPListItem重新创建类型,如果有任何反馈,我会很感激。

代码语言:javascript
复制
ContractManagementDataContext context = new ContractManagementDataContext(_url);
WorkflowTask task = context.Tasks.FirstOrDefault(t => t.Id ==5);
Approval a = new Approval(task.item);

public partial class Approval{
     public Approval(SPListItem item){
         //Set all properties here for workflowtask and approval type?
         //Wouldn't there be issues since it isn't attached to the datacontext?
    }

    public String SomeProperty{
        get{ //get from list item};
        set{ //set to list item};
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-02-22 16:27:56

对于列表中的所有ContentType,Linq2SharePoint将始终返回第一个公用基ContentTypes的对象。这不仅是因为必须使用某种描述的基类型来组合代码中的不同ContentTypes,而且它将只映射列表中所有ContentTypes上明确存在的字段。但是,可以访问由L2SP返回的底层SPListItem,从而确定ContentType并向下强制转换项。

作为从T4模板生成的自定义存储库层的一部分,我们向SPMetal生成的Item类添加了部分内容,该类实现了ICustomMapping以获取L2SP实体上通常不可用的数据。下面是一个简化的版本,它只获取ContentType和ModifiedDate来显示方法;尽管我们使用的完整类还映射了Modified By、Created Date/By、Attachments、Version、Path等,但原则对所有人都是相同的。

代码语言:javascript
复制
public partial class Item : ICustomMapping
{
private SPListItem _SPListItem;
public SPListItem SPListItem
{
    get { return _SPListItem; }
    set { _SPListItem = value; }
}
public string ContentTypeId { get; internal set; }
public DateTime Modified { get; internal set; } 

public virtual void MapFrom(object listItem) 
{ 
    SPListItem item = (SPListItem)listItem;
    this.SPListItem = item;
    this.ContentTypeId = item.ContentTypeId.ToString();
        this.Modified = (DateTime)item["Modified"]; 
}

public virtual void MapTo(object listItem) 
{ 
    SPListItem item = (SPListItem)listItem;  
        item["Modified"] = this.Modified == DateTime.MinValue ? this.Modified = DateTime.Now : this.Modified; 
}

public virtual void Resolve(RefreshMode mode, object originalListItem, object databaseObject) 
{ 
    SPListItem originalItem = (SPListItem)originalListItem; 
    SPListItem databaseItem = (SPListItem)databaseObject;

        DateTime originalModifiedValue = (DateTime)originalItem["Modified"]; 
        DateTime dbModifiedValue = (DateTime)databaseItem["Modified"];

    string originalContentTypeIdValue = originalItem.ContentTypeId.ToString(); 
    string dbContentTypeIdValue = databaseItem.ContentTypeId.ToString();

    switch(mode)
    {
        case RefreshMode.OverwriteCurrentValues:
                this.Modified = dbModifiedValue; 
            this.ContentTypeId = dbContentTypeIdValue;
            break;

        case RefreshMode.KeepCurrentValues:
                databaseItem["Modified"] = this.Modified; 
            break;

        case RefreshMode.KeepChanges:
                if (this.Modified != originalModifiedValue) 
                { 
                    databaseItem["Modified"] = this.Modified; 
                } 
                else if (this.Modified == originalModifiedValue && this.Modified != dbModifiedValue) 
                { 
                    this.Modified = dbModifiedValue; 
                }
            if (this.ContentTypeId != originalContentTypeIdValue) 
            { 
                throw new InvalidOperationException("You cannot change the ContentTypeId directly"); 
            } 
            else if (this.ContentTypeId == originalContentTypeIdValue && this.ContentTypeId != dbContentTypeIdValue) 
            { 
                this.ContentTypeId = dbContentTypeIdValue; 
            }                   
            break;
    } 
}
}

一旦在L2SP实体上有了可用的ContentType和底层SPListItem,就只需编写一个方法,通过基类型值和SPListItem中缺少的字段的额外数据的组合返回派生的ContentType实体的实例。

更新:我实际上没有一个示例转换器类,因为我们没有以这种方式使用上面的映射扩展到Item。然而,我可以想象这样的事情会起作用:

代码语言:javascript
复制
public static class EntityConverter
{
    public static Approval ToApproval(WorkflowTask wft) 
    {
        Approval a = new Approval();
        a.SomePropertyOnWorkflowTask = wft.SomePropertyOnWorkflowTask;
        a.SomePropertyOnApproval = wft.SPListItem["field-name"];
        return a;
    }
}

或者,您可以将一个方法放在WorkflowTask的部分实例上,以返回一个批准对象。

代码语言:javascript
复制
    public partial class WorkflowTask
    {
        public Approval ToApproval()
        {
            Approval a = new Approval();
            a.SomePropertyOnWorkflowTask = this.SomePropertyOnWorkflowTask;
            a.SomePropertyOnApproval = this.SPListItem["field-name"];
return a;
        }

        public LegalReview ToLegalReview()
        {
            // Create and return LegalReview as for Approval
        }
    }

在这两种情况下,您都需要确定从WorkflowTask的ContentTypeId属性中调用以获取派生类型的方法。这是我通常希望以这样或那样的形式生成的代码,因为它会非常重复,但这有点离题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9386437

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档