我有可能首先尝试这个,但这是我到目前为止所做的:
public List<int> AuthorIDs
{
get
{
var l = new List<int>();
using (var context = new GarbageEntities())
{
foreach (var author in context.Authors.Where(a => a.Books.Any(b => b.BookID == this.BookID)).ToList())
{
l.Add(author.AuthorID);
}
}
return l;
}
set; //compiler error
}
如果没有任何自定义逻辑,我将如何离开上面的setter?在过去,我认为你只会使用:
set { authorIDs = value; }
现在不起作用。
这个想法一开始就很糟糕吗?
修改
回答一些人的问题:我正在尝试将MVC与Data Annotation验证结合使用默认绑定,与Entity Framework 4.0相结合......并且我相信它失败了。
答案 0 :(得分:7)
不,这是不可能的。要么一切都是明确的,要么整个属性都是自动的。无论如何,在这种情况下,设定者似乎没有任何意义......根本就没有设定者。
另外,我认为你应该把它变成一种方法。这将使调用者更清楚它执行可能的长度计算。它也违反了在财产中执行复杂处理的准则。
答案 1 :(得分:4)
这个答案比简单地摆脱属性上的setter要宽一些 - 将它与其余的答案和注释结合起来,并取出有意义的位。希望最后的一点也有帮助,也许现在不行。
如果您在模型中使用它来进行数据绑定,因此希望将其作为属性公开,我会这样做:
public class BookModel
{
public IList<int> AuthorIds { get; set; }
}
创建一个服务,您将调用该服务来填充您的模型:
public class BookService()
{
public List<int> GetAuthorIDs(int bookId)
{
var authorIds = new List<int>();
using (var context = new GarbageEntities())
{
foreach (var author in context.Authors.Where(
a => a.Books.Any(b => b.BookID == bookId)))
{
authorIds.Add(author.AuthorID);
}
}
return authorIds;
}
}
在您的控制器中:
public ViewResult List(int id)
{
var model = new BookModel
{
AuthorIds = service.GetAuthorIDs(id)
};
return View(model);
}
我明确没有包括如何在控制器中实例化book服务。我的偏好是在运行时在构造函数中注入它,但这需要你有一个自定义控制器工厂 - 一次一个步骤。您可以在默认构造函数中新建它:
private readonly BookService service;
public BookController()
{
service = new BookService();
}
在一个理想的世界里,我会这样做:
private readonly BookService service;
public BookController(BookService service)
{
if(service == null)
throw new ArgumentException("service must be supplied");
this.service = service;
}
然而,默认的MVC控制器工厂期望控制器具有默认参数,因此使用构造函数注入执行此操作将需要更多的工作。
答案 2 :(得分:3)
默认的setter将在编译时创建一个支持变量,其名称如下:
[CompilerGenerated]
private string <AuthorIDs>k__BackingField;
由于这是在编译时创建的,因此在创建代码之前不能在代码中引用它,此外,在变量名中不允许使用尖括号(有意)。
由于这个原因,允许将某些内容存储在此变量中(这实际上就是自动setter所做的事情)是无用的,并且无法在将来的任何时候访问此值(在所有getter之后)这里不是一个自动获取器,它会返回完全不同的东西)
所以对于没有getter的summerise,会有(这是从这个支持变量中检索值的唯一方法),拥有私有的setter是没有意义的
答案 3 :(得分:2)
如果您想按照自己的方式行事,请执行以下操作:
private List<int> authorIDs;
public List<int> AuthorIDs
{
get
{
var l = new List<int>();
using (var context = new GarbageEntities())
{
foreach (var author in context.Authors.Where(a => a.Books.Any(b => b.BookID == this.BookID)).ToList())
{
l.Add(author.AuthorID);
}
}
return l;
}
set{authorIDs = value; //this does not make much sense though ... what are you trying to do by setting authorIDs?
}
}
但就像其他人说的那样,这对于一个属性来说太过分了,把它放在方法中,比如
public List<int> GetAuthorIDs(int bookId)
{
var l = new List<int>();
using (var context = new GarbageEntities())
{
foreach (var author in context.Authors.Where(a => a.Books.Any(b => b.BookID == bookId)).ToList())
{
l.Add(author.AuthorID);
}
}
return l;
}
答案 4 :(得分:0)
实际上有一种方法可以做到这一点:
public List<int> AuthorIDs
{
get
{
var l = new List<int>();
using (var context = new GarbageEntities())
{
foreach (var author in context.Authors.Where(a => a.Books.Any(b => b.BookID == this.BookID)).ToList())
{
l.Add(author.AuthorID);
}
}
return l;
}
set{
this.SetPropertyValue(page => page.AuthorIDs, value);
}
}