繁体   English   中英

将SharePoint列表项映射到C#类

[英]Mapping a SharePoint list item to a C# class

说我有:

public class SPListItem
{ 
     public override object this[string fieldName]
     {
       get
       {
         return this.GetValue(fieldName);
       }
       set
       {
         this.SetValue(fieldName, value, !this.HasExternalDataSource);
       }
     }
}

public class Bar
{
    public int Prop1 { get; set; } 
    public int Prop2 { get; set; } 
    public int Prop3 { get; set; } 
}

有什么办法可以做:

var fooInst = new SPListItem();
Bar barInst = (Bar)fooInst // or maybe Bar.FromFoo(Foo f) if handling the cast is not possible

然后有:

barInst.Prop1给我以下效果:

fooInst["Prop"];

是否没有为Bar中的每个属性实现getter和setter方法?

对于我的前雇主,我为SharePoint实现了DAO模式 不幸的是,我不被允许随身携带或发布代码...我使用批注和反射来解决名称,可选字段,类型转换等问题。我还为DTO对象编写了一个生成器。 但是说实话,LINQ可能会为您的案例解决相当大的工作。 或手动编写类,或为getter和setter编写代码生成器-所有这些都取决于项目的大小。

在实施我自己的DAO之前,我对LINQ to SQL有相当不好的经验,特别是当列被重命名,添加或删除时,我不喜欢这种行为,使用它也遇到性能问题。 这就是为什么我更喜欢自己的DAO模式,但是对于简单的任务,LINQ可能就足够了。 我在LINQ上的经验可能也已经过时,大约是7年前;)

Aaaaaand,我们开始。 此类从您的列表生成实体。 来自: https : //justsharepointthings.wordpress.com/2015/09/10/sharepoint-generate-c-poco-classes-from-an-existing-definition/

using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.SharePoint;

namespace Code_Generation {
    /// <summary>
    /// Generates List object entities from a site connection.
    /// </summary>
    public class SPListPocoGenerator {
        string parentDir = "GeneratedListPOCO/";
        string hiddenDir = "GeneratedListPOCO/HiddenLists/";

        private class PropertyString {
            private string _propStr;

            public PropertyString(string propStr) {
                _propStr = propStr;
                _properties = new Dictionary < string, string > ();
            }

            private Dictionary < string, string > _properties;
            public string this[string key] {
                get {
                    return _properties.ContainsKey(key) ? _properties[key] : string.Empty;
                }
                set {
                    if (_properties.ContainsKey(key)) {
                        _properties[key] = value;
                    } else {
                        _properties.Add(key, value);
                    }
                }
            }



            /// <summary>
            /// Replaces properties in the format {{propertyName}} in the source string with values from KeyValuePairPropertiesDictionarysupplied dictionary.nce you've set a property it's replaced in the string and you 
            /// </summary>
            /// <param name="originalStr"></param>
            /// <param name="keyValuePairPropertiesDictionary"></param>
            /// <returns></returns>
            public override string ToString() {
                string modifiedStr = _propStr;
                foreach(var keyvaluePair in _properties) {
                    modifiedStr = modifiedStr.Replace("{{" + keyvaluePair.Key + "}}", keyvaluePair.Value);
                }

                return modifiedStr;
            }
        }



        public string _classDefinitionStr = @
        "
using System;
using Microsoft.SharePoint;

public class {{EntityName}}
{
    private SPListItem listItem;
    public {{EntityName}}_InternalProperties InternalProperties
    {
        get; private set;
    }

    public {{EntityName}}(SPListItem li)
    {
        this.listItem = li;
        this.InternalProperties = new {{EntityName}}_InternalProperties(this.listItem);
    }

    {{PropertySections}}   
    public class {{EntityName}}_InternalProperties
    {
        private SPListItem listItem;

        public {{EntityName}}_InternalProperties(SPListItem li)
        {
            this.listItem = li;
        }

        {{HiddenPropertySections}}
        {{InternalPropertySections}}  
    }     
}";

        private const string _propertySectionStr = "\n\n\t" + @
        "public {{PropertyType}} {{PropertyName}}
    {   get { return listItem[Guid.Parse("
        "{{PropertyId}}"
        ")] as {{PropertyType}}; }
        set { listItem[Guid.Parse("
        "{{PropertyId}}"
        ")] = value; }}";

        /// <summary>
        /// Gets string identifying the field type
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        private string GetSafeTypeName(SPField field) {
            if (field.FieldValueType == null) {
                return "object"; //Not going to try to parse it further, this is enough.
            }

            var type = field.FieldValueType;

            if (type.IsValueType) {
                return type.FullName + "?";
            }
            return type.FullName;
        }

        public void GenerateForWeb(SPWeb web) {
            var blackList = new[] {
                "Documents", "Form Templates", "Site Assets", "Site Pages", "Style Library"
            };

            Directory.CreateDirectory(parentDir);
            Directory.CreateDirectory(hiddenDir);

            foreach(SPList list in web.Lists) {
                PropertyString _classDefinition = new PropertyString(_classDefinitionStr);

                string entityName = "SPL_" + list.Title.Replace(" ", "");
                _classDefinition["EntityName"] = entityName;

                foreach(SPField field in list.Fields) {
                    PropertyString propertySection = new PropertyString(_propertySectionStr);

                    propertySection["PropertyType"] = GetSafeTypeName(field); //field.FieldValueType.FullName; -> Returning Null often. Thanks, SharePoint!
                    propertySection["PropertyName"] = field.EntityPropertyName.Replace("_x0020_", "_");
                    propertySection["PropertyId"] = field.Id.ToString();

                    if (SPBuiltInFieldId.Contains(field.Id)) _classDefinition["InternalPropertySections"] += propertySection;
                    else if (field.Hidden) _classDefinition["HiddenPropertySections"] += propertySection;
                    else _classDefinition["PropertySections"] += propertySection;
                }

                if (list.Hidden || blackList.Contains(list.Title)) {
                    File.WriteAllText(hiddenDir + entityName + ".cs", _classDefinition.ToString());
                } else {
                    File.WriteAllText(parentDir + entityName + ".cs", _classDefinition.ToString());
                }
            }



        }

    }


}

您可以使用System.Dynamic命名空间中的ExpandoObject 尝试以下操作(未经测试):

public class SPListItemPropertyMapper
{
    private dynamic _expandoObject;

    public SPListItemPropertyMapper(SPListItem listItem)
    {
        _expandoObject = new ExpandoObject();
        foreach (SPField field in listItem.Fields)
        {               
            _expandoObject.Add(field.InternalName, listItem.GetFormattedValue(field.InternalName));
        }
    }

    public dynamic FieldValues
    {
        get { return _expandoObject; }
    }
}

用法:

SPListItem listItem; //your list item here
var propertyMapper = new SPListItemPropertyMapper(listItem);

var title = propertyMapper.FieldValues.Title;
var editor = propertyMapper.FieldValues.Editor;
var created = propertyMapper.FieldValues.Created;

等等。您应该考虑通过更多逻辑扩展foreach循环,以基于字段类型返回值,而不仅仅是使用GetFormattedValue

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM