Dynamics 365-六:客户端服务

参考文章

使用类

返回列

public sealed class ColumnSet : System.Runtime.Serialization.IExtensibleDataObject

Microsoft.Xrm.Sdk.Query:用于从数据库检索一个或多个记录的方法和消息。查询为Columns属性中包含的属性返回非空值。列集中未包含的属性将包含空值。如果列集包含对检索无效的属性,则将忽略这些属性,并且不会为这些属性返回任何值

构造函数

创建新实例

public ColumnSet();

创建新实例,返回所有列

public ColumnSet(bool allColumns);

创建新实例,返回指定列

public ColumnSet(string[] columns);

服务管理对象(重点)

public interface IOrganizationService

Microsoft.Xrm.Sdk.IOrganizationService:提供对组织的元数据和数据的编程访问

公共方法

创建记录

传入记录实体,返回新创建的记录的ID

public Guid Create (Microsoft.Xrm.Sdk.Entity entity);

删除记录

传入实体的逻辑名称,根据记录的 id 删除记录

参数:

  • entityName:实体的逻辑名称
  • id:删除的记录 id
public void Delete (string entityName, Guid id);

更新记录

参数:entity:在记录中设置了一个或多个要更新的属性的实体实例

public void Update (Microsoft.Xrm.Sdk.Entity entity);

获取某个实体的单条数据

public Microsoft.Xrm.Sdk.Entity Retrieve (
    string entityName, Guid id, 
    Microsoft.Xrm.Sdk.Query.ColumnSet columnSet
);

获取某个实体的多条数据

public Microsoft.Xrm.Sdk.EntityCollection RetrieveMultiple(
    Microsoft.Xrm.Sdk.Query.QueryBase query
);

QueryBase有三个派生类,分别是QueryByAttributeQueryExpression以及 FetchExpression

示例一:使用 QueryByAttribute 查询

QueryByAttribute 类属性如下:

属性 说明
EntityName 指定检索哪种类型的实体。一个查询表达式仅检索一个实体类型集合
ColumnSet 指定要检索的属性(列)的集合
Attributes 指定查询中选择的属性集合
Values 指定查询执行时要查找的属性值
Orders 指定从查询返回记录的顺序
PageInfo 指定从查询返回的页数和每页的记录数

借由QueryByAttribute,形成的等价SQL语句如下:

select
	[ColumnSet]
from 
	[EntityName]
where
	Attibutes[1] = Values[1] And
	Attibutes[2] = Values[2] And
	Attibutes[N] = Values[N]

应用实例如下:

// 1.创建QueryByAttribute实例,指定待检索实体的逻辑名称
QueryByAttribute queryByAttribute = new QueryByAttribute("account");

// 2.指定返回结果包含的数据列集合
queryByAttribute.ColumnSet = new ColumnSet("name", "address1_city", "emailaddress1");

// 3.指定检索条件
// 3.1指定检索条件的列字段
queryByAttribute.Attributes.AddRange("address1_city");
// 3.2指定检索条件中的列值
queryByAttribute.Values.AddRange("Detroit");

// 4.调用组织服务的RetrieveMultiple方法
EntityCollection retrieved = _serviceProxy.RetrieveMultiple(queryByAttribute);

// 5.遍历返回结果
foreach (var c in retrieved.Entities){
    Console.WriteLine("Name: " + c.Attributes["name"]);
}

示例二:使用 QueryExpression 查询

无,需要的另行查阅

示例三:使用 FetchExpression 查询

string query = 
    @"<fetch mapping='logical' version='1.0'>
        <entity name='account' >
            <attribute name='name'/>
        </entity>
    </fetch> ";
FetchExpression fetchExpression = new FetchExpression(query);
EntityCollection retrieved = _serviceProxy.RetrieveMultiple(fetchExpression);

执行一个请求操作

public Microsoft.Xrm.Sdk.OrganizationResponse Execute(
    Microsoft.Xrm.Sdk.OrganizationRequest request
);

Execute 方法的返回值是OrganizationResponse的派生类,与请求消息的名称唯一的不同就是后缀名称。例如,如果Execute方法的输入参数是AssignRequest,那么对应的返回值就是一个AssignResponse类的对象,总之,请求和响应成对出现

实例一:一个请求

// 1.实例化AssignRequest对象,并设置Assignee苏醒以及Target属性
AssignRequest assign = new AssignRequest
{
    Assignee = new EntityReference(“systemuser”, _otherUserId),
    Target = new EntityReference(“account”, _accountId)
}
// 2.执行请求
AssignResponse respose = (AssignResponse)_service.Execute(assign);

实例二:多个请求,批量添加

// 1.实例化ExecuteTransactionRequest对象
var request = new ExecuteTransactionRequest()
{
    ReturnResponses = true,
    Requests = new OrganizationRequestCollection()
};
// 2.循环添加创建请求
model.InsertList.ForEach(entity =>
{
    var imodel = new CreateRequest() { Target = entity };
    request.Requests.Add(imodel);
});
// 3.执行请求
service.Execute(request);

在记录之间创建链接

从签名可以看出,功能是依据输入参数 relationship 指定的关联,将主要实体(entityName)的某个实例(entityId)与一组相关实体(relatedEntities)进行连接

从数据库角度讲,就是设置实例的 primary{实体名}id字段值为联系人的主键值,对于多对多关系而言,系统会自动向交叉表插入数据

public void Associate (
    string entityName, Guid entityId, 
    Microsoft.Xrm.Sdk.Relationship relationship,
    Microsoft.Xrm.Sdk.EntityReferenceCollection relatedEntities
);

示例一:用户设置(多)角色

// 1.创建用户
Entity user = new Entity("tb_user");
user["name"] = "libai";
Guid uid = service.Create(user);

// 2.创建角色集合
EntityReferenceCollection roles = new EntityReferenceCollection();
roles.Add(new EntityReference("tb_role", rid1));
roles.Add(new EntityReference("tb_role", rid2));

// 3.创建关联实例,指定当前使用的关联
Relationship relationship = new Relationship("tb_role_primary_tb_user");

// 4.建立连接
service.Associate("tb_user", uid, relationship, roles);

删除记录之间链接

DisassociateAssociate方法是互逆的两个操作,且输入参数一致;调用时,系统会根据relationship关联,找到相关实体的外键字段,而后,将集合中的记录的该外键值置为null,对于多对多关系而言,系统会根据根据entityId以及集合中的每个元素的主键值,从中间表中删除该数据

public void Disassociate (
    string entityName, Guid entityId, 
    Microsoft.Xrm.Sdk.Relationship relationship,
    Microsoft.Xrm.Sdk.EntityReferenceCollection relatedEntities
);

客户端工厂

public static class ServiceConfigurationFactory

Microsoft.Xrm.Sdk.Client.ServiceConfigurationFactory:表示用于创建服务配置的客户端工厂

静态方法

创建服务管理对象

参数:

  • TService:指定服务类型:IDiscoveryService IOrganizationService
  • serviceUri:指定服务的 URI

返回值:

  • IServiceManagement<TService>IServiceManagement<TService> 服务管理对象
public static IServiceManagement<TService> CreateManagement<TService> (Uri serviceUri);

示例代码

配置文件

<appSettings>
    <!-- On-premises using Windows integrated security -->
    <add key="DiscoveryServiceAddress" value="http://ip:5555/ewdev/XRMServices/2011/Discovery.svc"/> 
    <add key="UserName" value="weiyg"/> 
    <add key="Password" value="P@ssw123rd"/>
    <!--<add key="Domain" value="domain"/> -->
    <add key="Domain" value=""/> 
    <add key="OrganizationUniqueName" value="ewdev"/> 
    <add key="OrganizationServiceAddress" value="http://ip:5555/ewdev/XRMServices/2011/Organization.svc"/>
</appSettings>

代码文件

using System;
using Microsoft.Xrm.Sdk.Client;
using System.Configuration;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;

namespace ExternalConnectionCRM
{
    class Program
    {
        static void Main(string[] args)
        {
            // 0.获取uri地址
            string organizationUri 
                = ConfigurationManager.AppSettings["OrganizationServiceAddress"];

            // 1.创建身份验证对象
            IServiceManagement<IOrganizationService> orgServiceManagement =
                    ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(organizationUri));

            // 2.获取服务的标识提供程序正在使用的身份验证类型
            AuthenticationProviderType orgpointType 
                = orgServiceManagement.AuthenticationType;

            // 3.获取客户端用户登录凭据
            AuthenticationCredentials orgcredentials = GetCredentials(orgpointType);
            
            // 4.OrganizationServiceProxy 服务
            using (OrganizationServiceProxy organizationProxy
                   = GetProxy<IOrganizationService,
                OrganizationServiceProxy>(orgServiceManagement, orgcredentials))
            {
                #region U
                ColumnSet attributes = new ColumnSet(new string[] { "mcs_state", "ownerid" });
                Entity entity = organizationProxy.Retrieve("mcs_tc_order", new Guid("xxx"), attributes);
                Console.WriteLine(((OptionSetValue)entity["mcs_state"]).Value);
                entity.Attributes["mcs_state"] = new OptionSetValue(2);
                organizationProxy.Update(entity);
                #endregion

                #region D
                organizationProxy.Delete("mcs_tc_order", new Guid("xxx"));
                #endregion

                #region R
                ColumnSet attributes = new ColumnSet(new string[] { "mcs_state", "ownerid" });
                Entity entity = organizationProxy.Retrieve("mcs_tc_order", new Guid("xxx"), attributes);
                Console.WriteLine(((OptionSetValue)entity["mcs_state"]).Value);
                #endregion

                #region C
                Entity newEntity = new Entity("mcs_tc_order");
                newEntity["mcs_state"] = new OptionSetValue(1);
                newEntity["mcs_approvalstatus"] = new OptionSetValue(1);
                Guid id = organizationProxy.Create(newEntity);
                Console.WriteLine(id);
                #endregion

            }
        }

        private static AuthenticationCredentials GetCredentials(AuthenticationProviderType endpointType)
        {
            string _userName = ConfigurationManager.AppSettings["UserName"];
            string _password = ConfigurationManager.AppSettings["Password"];
            string _domain = ConfigurationManager.AppSettings["Domain"];

            AuthenticationCredentials authCredentials = new AuthenticationCredentials();
            switch (endpointType)
            {
                case AuthenticationProviderType.ActiveDirectory:
                    authCredentials.ClientCredentials.Windows.ClientCredential = 
                        new System.Net.NetworkCredential(_userName, _password, _domain);
                    break;
                case AuthenticationProviderType.Federation:
                case AuthenticationProviderType.OnlineFederation:
                    authCredentials.ClientCredentials.UserName.UserName = _userName;
                    authCredentials.ClientCredentials.UserName.Password = _password;
                    break;
                default:
                    break;
            }

            return authCredentials;
        }

        private static TProxy GetProxy<TService, TProxy>(IServiceManagement<TService> serviceManagement,
            AuthenticationCredentials authCredentials)
            where TService : class
            where TProxy : ServiceProxy<TService>
        {
            Type classType = typeof(TProxy);

            if (serviceManagement.AuthenticationType != AuthenticationProviderType.ActiveDirectory)
            {
                AuthenticationCredentials tokenCredentials = serviceManagement.Authenticate(authCredentials);
                return (TProxy)classType
                     .GetConstructor(new Type[] { typeof(IServiceManagement<TService>),
                         typeof(SecurityTokenResponse) })
                     .Invoke(new object[] { serviceManagement, tokenCredentials.SecurityTokenResponse });
            }

            return (TProxy)classType
                .GetConstructor(new Type[] { typeof(IServiceManagement<TService>),
                    typeof(System.ServiceModel.Description.ClientCredentials) })
                .Invoke(new object[] { serviceManagement, authCredentials.ClientCredentials });
        }
    }
}
posted @ 2021-01-06 16:37  位永光  阅读(498)  评论(0编辑  收藏  举报