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有三个派生类,分别是QueryByAttribute、QueryExpression以及 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);
删除记录之间链接
Disassociate和Associate方法是互逆的两个操作,且输入参数一致;调用时,系统会根据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 });
        }
    }
}
 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号