考虑以下课程
public class AccountGroup : Entity<int>
{
public AccountGroup()
{
Accounts = new HashSet<Account>();
Groups = new HashSet<AccountGroup>();
}
// option 1 - read only properties
public bool IsRoot { get { return Parent == null; } }
public bool IsLeaf { get { return !Groups.Any(); } }
public Account MainAccount { get { return Accounts.FirstOrDefault(a=>a.Type == AccountType.MainAccount); } }
// option 2 - parameter-less methods
//public bool IsRoot() { return Parent == null; }
//public bool IsLeaf() { return !Groups.Any(); }
//public Account GetMainAccount() { return Accounts.FirstOrDefault(a => a.Type == AccountType.MainAccount); }
public string Name { get; set; }
public string Description { get; set; }
public virtual ISet<Account> Accounts { get; private set; }
public virtual ISet<AccountGroup> Groups { get; private set; }
public virtual AccountGroup Parent { get; set; }
}
如果我想“丰富”上面的课程,我应该使用哪种方法。
我是否应该使用只读参数知道EF不喜欢它们(尝试在Where子句中使用IsRoot抛出ex,The specified type member 'IsRoot' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
或者我应该使用无参数方法(不确定会有什么缺点)
一般情况下(不考虑EF),当功能相同时,考虑上述哪种方法是优选的(即如果我调用.IsRoot
或.IsRoot()
,我会获得相同的功能)
答案 0 :(得分:2)
IsRoot
对我来说更像是一种财产。它表示对象的当前状态,除了报告状态之外,实际上并不执行任何操作,并且.NET中的getter / setter通常是属性。
还有其他需要考虑的事项,JSON / XML序列化程序不会序列化IsRoot()
,但会将IsRoot
作为属性。一般来说,.NET中的很多东西都取决于属性,所以通常它们是更好的选择。
EF也不喜欢IsRoot()
,它只是不知道如何将IsRoot转换为SQL,无论它是属性还是方法。
答案 1 :(得分:0)
一般而言(正如您所说,不考虑EF的限制),在此特定上下文中域模型的方法可能是只读属性。
考虑该属性只是检查状态,而不是以任何方式修改它。只读属性在对象之外传达它只返回一条信息。另一方面,一种方法可能具有破坏性,因为它可能会修改信息。
如果方法当然返回void
,则情况尤其如此,这不是这里的情况,所以这可能被视为边界问题(甚至不是没有语言的问题“属性“但只是使用访问器方法,这是”属性“所做的。
我的投票是在检查状态时的属性,以及在命令对象修改状态时的方法。
答案 2 :(得分:0)
您是否已尝试使用[NotMapped]装饰IsRoot
? NotMapped属性应该阻止Entity Framework抱怨它无法持久化的属性,并允许您将其表达为属性。