0

我正在为 CRM 2011 构建一个 silverlight 应用程序,我想知道从 CRM 系统中检索数据的最佳方法是什么。

我已在我的组织中链接为服务参考,并且能够访问它。我见过几种不同的方法来检索数据,但它们看起来都相当复杂。有没有像我们可以在插件中使用的东西,例如 fetch XMl 查询或简单的 Service.Retrieve 方法?

谢谢

4

2 回答 2

1

如果向项目添加服务引用,则可以使用 LINQ 查询数据集。您可以从自定义区域下的开发人员资源下载 CSDL。

private FelineSoftContext context;
private System.String serverUrl;
private DataServiceCollection<SalesOrder> _orders;

public MainPage()
    {
        InitializeComponent();
        serverUrl = (String)GetContext().Invoke("getServerUrl");
        //Remove the trailing forward slash returned by CRM Online
        //So that it is always consistent with CRM On Premises
        if (serverUrl.EndsWith("/"))
            serverUrl = serverUrl.Substring(0, serverUrl.Length - 1);

        Uri ODataUri = new Uri(serverUrl + "/xrmservices/2011/organizationdata.svc/", UriKind.Absolute);
        context = new FelineSoftContext(ODataUri) { IgnoreMissingProperties = true };

        var orders = from ord in context.SalesOrderSet
                     orderby ord.Name
                     select new SalesOrder
                     {
                         Name = ord.Name,
                         SalesOrderId = ord.SalesOrderId
                     };

        _orders = new DataServiceCollection<SalesOrder>();
        _orders.LoadCompleted += _orders_LoadCompleted;
        _orders.LoadAsync(orders);
    }

    void _orders_LoadCompleted(object sender, LoadCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            if (_orders.Continuation != null)
            {
                _orders.LoadNextPartialSetAsync();
            }
            else
            {
                OrderLookup.ItemsSource = _orders;
                OrderLookup.DisplayMemberPath = "Name";
                OrderLookup.SelectedValuePath = "Id";
            }
        }
    }

您还需要在您的类中添加一个方法,如下所示:

private static ScriptObject GetContext()
    {
        ScriptObject xrmProperty = (ScriptObject)HtmlPage.Window.GetProperty("Xrm");
        if (null == xrmProperty)
        {
            //It may be that the global context should be used
            try
            {

                ScriptObject globalContext = (ScriptObject)HtmlPage.Window.Invoke("GetGlobalContext");

                return globalContext;
            }
            catch (System.InvalidOperationException)
            {
                throw new InvalidOperationException("Property \"Xrm\" is null and the Global Context is not available.");
            }

        }

        ScriptObject pageProperty = (ScriptObject)xrmProperty.GetProperty("Page");
        if (null == pageProperty)
        {
            throw new InvalidOperationException("Property \"Xrm.Page\" is null");
        }

        ScriptObject contextProperty = (ScriptObject)pageProperty.GetProperty("context");
        if (null == contextProperty)
        {
            throw new InvalidOperationException("Property \"Xrm.Page.context\" is null");
        }

        return contextProperty;
    }

您将需要添加一个额外的类库并将以下代码放入其中。更改类名以匹配您导出的上下文:

partial class FelineSoftContext
{

    #region Methods
    partial void OnContextCreated()
    {
        this.ReadingEntity += this.OnReadingEntity;
        this.WritingEntity += this.OnWritingEntity;
    }
    #endregion

    #region Event Handlers
    private void OnReadingEntity(object sender, ReadingWritingEntityEventArgs e)
    {
        ODataEntity entity = e.Entity as ODataEntity;
        if (null == entity)
        {
            return;
        }

        entity.ClearChangedProperties();
    }

    private void OnWritingEntity(object sender, ReadingWritingEntityEventArgs e)
    {
        ODataEntity entity = e.Entity as ODataEntity;
        if (null == entity)
        {
            return;
        }

        entity.RemoveUnchangedProperties(e.Data);
        entity.ClearChangedProperties();
    }
    #endregion
}

public abstract class ODataEntity
{
    private readonly Collection<string> ChangedProperties = new Collection<string>();

    public ODataEntity()
    {
        EventInfo info = this.GetType().GetEvent("PropertyChanged");
        if (null != info)
        {
            PropertyChangedEventHandler method = new PropertyChangedEventHandler(this.OnEntityPropertyChanged);

            //Ensure that the method is not attached and reattach it
            info.RemoveEventHandler(this, method);
            info.AddEventHandler(this, method);
        }
    }

    #region Methods
    public void ClearChangedProperties()
    {
        this.ChangedProperties.Clear();
    }

    internal void RemoveUnchangedProperties(XElement element)
    {
        const string AtomNamespace = "http://www.w3.org/2005/Atom";
        const string DataServicesNamespace = "http://schemas.microsoft.com/ado/2007/08/dataservices";
        const string DataServicesMetadataNamespace = DataServicesNamespace + "/metadata";

        if (null == element)
        {
            throw new ArgumentNullException("element");
        }

        List<XElement> properties = (from c in element.Elements(XName.Get("content", AtomNamespace)
                                               ).Elements(XName.Get("properties", DataServicesMetadataNamespace)).Elements()
                                     select c).ToList();

        foreach (XElement property in properties)
        {
            if (!this.ChangedProperties.Contains(property.Name.LocalName))
            {
                property.Remove();
            }
        }
    }

    private void OnEntityPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (!this.ChangedProperties.Contains(e.PropertyName))
        {
            this.ChangedProperties.Add(e.PropertyName);
        }
    }
    #endregion
}
于 2013-11-29T11:33:32.187 回答
0

我会建议你使用Silvercrmsoap,它很容易使用。我在我的 Silverlight 项目中使用了它。

于 2012-12-17T11:03:21.773 回答