确保给定输入(纯函数)的输出相同?

时间:2017-02-26 17:44:20

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

在我尝试以更实用的方式编程时,我提出了以下静态函数:

public static class BaseService
{
    public static T EntityGet<T>(Guid id, XrmServiceContext xrmServiceContext) where T : Entity
    {
        return xrmServiceContext.CreateQuery<T>().Single(query => query.Id == id);
    }
}

我们如何确保它是确定性的并始终为指定的输入返回相同的值?

请注意 XrmServiceContext 是一个存储库,可能会根据连接是启动还是关闭而抛出。

我们是否应该将返回类型包装成 Maybe ? :

public static Maybe<T> EntityGet<T>(Guid id, XrmServiceContext xrmServiceContext) where T : Entity
{
    return xrmServiceContext.CreateQuery<T>().Single(query => query.Id == id).ToMaybe();
}

这样我们可以100%确定返回值。

问题: Maybe 更改之后,无论存储库是启动还是关闭,我们现在都可以拥有完全确定的行为吗?

2 个答案:

答案 0 :(得分:2)

此代码xrmServiceContext.CreateQuery<T>().Single(query => query.Id == id).ToMaybe();存在问题,因为IQueryable.Single如果没有与查询匹配则会抛出InvalidOperationException

你需要在这里使用IQueryable.SingleOrDefault来避免异常并返回一个空值(假设你想要一个null。)你仍然需要将它包装在Try / Catch中来处理数据库中断等问题,设置Try是便宜的,但Catch可能很昂贵,所以我们要避免将它用于逻辑。通过使用SingleOrDefault处理最常见的异常,因为Id不存在,并且允许Catch仅处理意外(网络故障等)

public static T EntityGet<T>(Guid id, OrganizationServiceContext xrmServiceContext) where T : Entity
{           
    try
    {
        return xrmServiceContext.CreateQuery<T>().SingleOrDefault(query => query.Id == id);
    }
    catch (Exception)
    {
        // Log the exception or this could create a debugging nightmare down the road!!!
        return default(T);
    }            
}

如果您想使用Functional.Maybe库来编写,可以:

public static Maybe<T> EntityGet<T>(Guid id, OrganizationServiceContext xrmServiceContext) where T : Entity
{
    try
    {
        return xrmServiceContext.CreateQuery<T>().SingleOrDefault(query => query.Id == id).ToMaybe();
    }
    catch (Exception)
    {
        // Log the exception or this could create a debugging nightmare down the road!!!
        return Maybe<T>.Nothing;
    }
}

答案 1 :(得分:1)

你可以把你的电话包裹起来试试,最后,总是会回来一个,但我不确定这是我推荐的行动方案。这意味着检索实体的每个调用站点都必须处理可能的检查,然后决定如果失败则该怎么做。

在这种情况下,而不是追求“完美” enter image description here 我接受错误发生了,它们会冒出来。此外,由于您正在处理数据库,因此无法保证该值将存在于数据库中,或者它将是相同的值(未更新)。