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 });
}
}
}