如何在运行时绑定到特定的IQueryable

时间:2017-02-24 20:18:35

标签: c# .net visual-studio dynamics-crm-2011

如何避免重复代码?

我有一个控制器 - >服务架构,控制器将调用服务中的方法。例如,下面我们有一个AccountController,会在GetCrmAccount上调用AccountService

    public class AccountController : ApiController
    {
        private readonly IAccountService _AccountService;

        [Route("Account({AccountGuid:guid})", Name = "GetAccountByGuid")]
        [HttpGet]
        [CacheOutput(ServerTimeSpan = 300)]
        public Account GetAccountByGuid(Guid AccountGuid)
        {
            var Account = _AccountService.GetCrmAccount(AccountGuid);
            return Account;
        }
}

我的服务:

    public class AccountService : IAccountService
{
    private readonly XrmServiceContext _xrmServiceContext;

    public AccountService(XrmServiceContext xrmServiceContext)
    {
        _xrmServiceContext = xrmServiceContext;
    }
    public chr_servicelocation GetCrmLocation(Guid locationGuid)
    {
        return _xrmServiceContext.chr_servicelocationSet.FirstOrDefault(x => x.Id == locationGuid);
    }

我的问题是我对其他控制器的要求非常相似。例如,我可以拥有一个名为AccountLeadsController的控制器,它将拥有自己的服务AccountLeadsService,它将具有相同的方法GetCrmAccountLead,它也将返回:

_xrmServiceContext.AccountLeadSet.FirstOrDefault(x => x.Id == accountLeadGuid);

有没有必要为我的解决方案中的每个服务创建此方法,有没有办法可以抽象出这种行为?

以下是具有IQueryables的类的定义:

    /// <summary>   Gets CRM Account by Guid. </summary>
    /// <param name="AccountGuid">  Guid of the Account to fetch. </param>
    /// <returns>   The CRM Account. </returns>
    public chr_serviceAccount GetCrmAccount(Guid AccountGuid)
    {
        return _xrmServiceContext.AccountSet.FirstOrDefault(x => x.Id == AccountGuid);
    }

/// <summary>
    /// Represents a source of entities bound to a CRM service. It tracks and manages changes made to the retrieved entities.
    /// </summary>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("CrmSvcUtil", "5.0.9690.3339")]
    public partial class XrmServiceContext : Microsoft.Xrm.Sdk.Client.OrganizationServiceContext
    {

        /// <summary>
        /// Constructor.
        /// </summary>
        public XrmServiceContext(Microsoft.Xrm.Sdk.IOrganizationService service) : 
                base(service)
        {
        }

        /// <summary>
        /// Gets a binding to the set of all <see cref="Xrm.Account"/> entities.
        /// </summary>
        public System.Linq.IQueryable<Xrm.Account> AccountSet
        {
            get
            {
                return this.CreateQuery<Xrm.Account>();
            }
        }

        /// <summary>
        /// Gets a binding to the set of all <see cref="Xrm.AccountLeads"/> entities.
        /// </summary>
        public System.Linq.IQueryable<Xrm.AccountLeads> AccountLeadsSet
        {
            get
            {
                return this.CreateQuery<Xrm.AccountLeads>();
            }
        }

        /// <summary>
        /// Gets a binding to the set of all <see cref="Xrm.ActivityMimeAttachment"/> entities.
        /// </summary>
        public System.Linq.IQueryable<Xrm.ActivityMimeAttachment> ActivityMimeAttachmentSet
        {
            get
            {
                return this.CreateQuery<Xrm.ActivityMimeAttachment>();
            }
        }

        /// <summary>
        /// Gets a binding to the set of all <see cref="Xrm.ActivityParty"/> entities.
        /// </summary>
        public System.Linq.IQueryable<Xrm.ActivityParty> ActivityPartySet
        {
            get
            {
                return this.CreateQuery<Xrm.ActivityParty>();
            }
        }
...
}

2 个答案:

答案 0 :(得分:1)

也许可以使用扩展方法+泛型?

有些事情:

public static XrmServiceContextExtensions
{

     public static T GetEntityRecordById<T>(this XrmServiceContext ctx, Guid Id) where T: Entity {
      return ctx.CreateQuery<T>().Where(e => e.Id == Id).FirstOrDefault();
     }

}

但是想知道,为什么不直接使用XrmServiceContext?

例如,我要做的就是保持简单,就是在我的Web应用程序中,我只是在控制器级别保留对IOrganizationService的引用,然后我可以使用它来创建XrmServiceContext实例,以及我可以使用相同的IOrganizationService引用,使用FakeXrmEasy从单元测试项目中注入虚假服务。

答案 1 :(得分:0)

我来看看DLaB.Xrm(Nuget包)中的扩展方法。它提供了针对IOrganizationService的通用扩展方法,因此它只是

service.GetEntity<Account>(id);