我有一个课程,我想让它从数据库中获取记录。我需要确保最多只有一条记录。根据OrderId,记录应该与该类匹配。
我觉得属性getter比一个方法更有意义,但我知道属性getter应该avoid throwing Exceptions和.Single()/.SingleOrDefault()
最终会抛出一个。我觉得这种方法可能会让人们认为每次都是从数据库中取出来的。无论哪种方式,我都将结果缓存在本地字段中。
这样的事情的最佳做法是什么?我有一个关于我的代码如下所示的例子。
注意:我知道理想情况下,我们在数据库列上有一个唯一索引,以确保它是唯一的,但我们无法对供应商数据库进行处理使用
class OrderDetails
{
DbOrder _order;
string OrderId { get; set; }
DbOrder Order // property way
{
get{
if (this._order == null)
this._order = dbContext.Where(x => x.OrderId == this.OrderId).SingleOrDefault();
return _order;
}
}
DbOrder GetOrder() // method way
{
if (this._order == null)
this._order = dbContext.Where(x => x.OrderId == this.OrderId).SingleOrDefault();
return _order;
}
}
答案 0 :(得分:2)
我会说,如果需要,属性应该总是引发异常,与任何地方一样(就像可能的情况一样应该避免)。
更重要的是,我认为属性不应该有“副作用”,虽然你的属性并不严格,但这是我能把它比作最接近的东西。当方法可能更具描述性时,对于属性来说,似乎“要做很多事”(打开数据库连接,查询数据,管道结果):你有点期望一种方法可以做更多的特殊工作
答案 1 :(得分:0)
花一些时间自己思考一下你的班级OrderDetails
代表什么:
如果OrderDetails
代表第一个,那么它只是一些只有get和set属性的POCO。
显然,您的OrderDetails
代表第二名。您的课程旨在简化对订单详细信息存储的访问。它还隐藏了存储,因此如果存储发生更改(数据库更改结构,或者不再是数据库,而是内存数据),则您的类的用户不必更改。
OrderDetails
的功能也更像access to order details
,因为类OrderDetails
的两个对象并不意味着两个订单详细信息,而是两个访问相同订单详细信息的方法。< / p>
如果您不是这个意思,但是您希望每个订单详细信息对象都代表其自己的订单详细信息,请考虑更改类,使其包含订单详细信息的获取数据,而不是获取数据的某些访问权限。还可以创建一些获取数据的函数,并返回带有获取数据的对象。
考虑制作像OrderDetails.Create(...)
这样的静态函数,甚至更好,创建一个order detail factory class
,为您填充所需数据的OrderDetail
个对象。
如果您已将数据与方法分离以获取数据,那么您的问题将得到解答:如果获取数据不成功,获取数据的方法将引发异常。包含所获取数据的POCO对象不必引发异常:数据本身没有错误
如果您真的想要,您的OrderDetail
不是订单的详细信息,而是获取订单详细信息的一些访问权限,那么获取订单的详细信息显然不是访问对象的属性,而是此访问对象的一些功能。
将订单详细信息与订单详细信息存储的访问分开的另一个原因是数据的一致性。如果您的订单明细具有一些相关的属性,并且您将通过单独的调用从存储中获取它们,您如何保证您的相关数据在第一次和第二次调用之间不会发生变化?
例如:在单独的电话中获取邮政编码和城市的地址。如果您查询的人的数据在您的第一次和第二次通话之间发生变化,因为此人正在移动,那么您可以获得旧邮政编码和新城市
总结:确保您清楚地了解设计的哪些部分代表数据本身,或者获取数据的某些部分,并相应地设计您的类。数据类将使用属性get / set填充,Access类将填充返回数据类的函数