在我尝试以更实用的方式编程时,我提出了以下静态函数:
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 更改之后,无论存储库是启动还是关闭,我们现在都可以拥有完全确定的行为吗?
答案 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)