【问题标题】:How to define use the same model within the model如何定义在模型内使用相同的模型
【发布时间】:2016-10-06 02:56:45
【问题描述】:

在我的 SessionView 模型中,我试图将数据库中的数据分配给一个局部变量,然后将该数据分配给相关的公共属性(而不是在控制器中进行)。

我正在尝试通过使用以下代码来实现这一点,但是在查询数据时它会崩溃,大概是因为我在其中定义了 same 模型...

public class SessionView : BaseViewModel
{
    public int SessionId { get; set; }

    private SessionView data
    {
        get
        {
            return (from s in db.Sessions
                    where s.SessionId == SessionId
                    select new SessionView
                    {
                        CourseId = s.CourseId
                        // ... lots of other properties
                    }).FirstOrDefault();
        }
        set { }
    }

    public int CourseId { get { return data.CourseId; } set { } }
    // ... lots of other properties
}

有什么聪明的方法可以做到这一点而不会出错?

谢谢。

【问题讨论】:

  • 这是一个 ASP.NET 还是 Windows 应用程序?
  • 你遇到了什么错误?
  • 如果您使用的是 EF,您可以让 EF 使用延迟加载为您处理此问题。
  • @glenn-ferrie 这是一个 ASP.Net MVC 应用程序
  • @wilsjd 在视图中,当它尝试获取属性时,没有进行进一步的处理,站点仍在运行,浏览器保持白色,我电脑上的风扇越来越响!

标签: c# model-view-controller models


【解决方案1】:

我认为最好的方法是将数据检索放在构造函数中: 这样,每次有人在此类中引用时,您只需检索一次数据,从而减少检索开销并优化您的代码。

简单来说,每次我使用变量data 时,我都会从数据库中查询它。

public class SessionView : BaseViewModel
{
    private SessionView _sessionView;
    public int SessionId { get; set; }

    public SessionView() 
    {
        _sessionView = new SessionView();
        _sessionView.data = from s in db.Sessions
                    where s.SessionId == SessionId
                    select new SessionView
                    {
                        CourseId = s.CourseId
                        // ... lots of other properties
                    }).FirstOrDefault();
    }
    private SessionView data
    {
        get
        {
            return _sessionView.data
        }
        set { }
    }

    public int CourseId { get { return data.CourseId; } set { } }
    // ... lots of other properties
}

【讨论】:

  • 感谢您的回复。我最初是从控制器中检索数据,但在阅读了模型应该如何“胖”而控制器“瘦”之后,我认为这将是一个好主意。此外,它不会在代码的各个部分使用相同的 linq 来填充视图模型,而是集中在此处。
  • 我认为问题在于无法在处理 linq 之前为 SessionId 分配值。我使用了SessionView sessionView = new SessionView { SessionId = 5 };,但类中的 SessionId 为 0。
【解决方案2】:

您从哪里了解到控制器应该是瘦模型而不是胖模型?控制器中的业务逻辑不是很好,因为它比在业务逻辑层中更难重用,但不要将其与仅数据库访问混淆;如果你能提供帮助,那绝对应该远离模型。

这种工作,为你的模型分配一个数据库值——这正是 MVC 中的控制器的目的。我会选择这样的。

型号

public class SessionView : BaseViewModel
{
    public int SessionId { get; set; }
    public int CourseId { get; set; }
    // ... lots of other properties
}

控制器

public class HomeController : Controller
{
    public ActionResult Index(){
        var context = new MyContext();
        var firstSession = context.Sessions.First();
        var viewModel = new SessionView 
        {
            SessionId = firstSession.SessionId,
            CourseId = firstSession.CourseId,
            //keep populating here if you need
        };
        return View(viewModel);
    }
}

【讨论】:

  • 感谢您的回复,我想我现在开始意识到这一点。我通过对setset 的所有属性进行数据库检索来使其工作。这样做的好处是它将SessionView 的人口保持在一个地方,但它看起来确实有点混乱,正如@Luiso 所说,只有在需要时才会检索属性,所以这可能在视图中。
  • 如果它适合你,那就太棒了。肯定有不止一种方法可以解决它。只要您有一种适合您的方法,并且您可以捍卫为什么它更好,那么您就应该去做。
【解决方案3】:

我认为您的问题是模型上的数据加载实际上是在视图中进行的,这在 MVC 中是一种不好的做法,相反您应该在控制器上通过使用服务来执行此操作,例如:

public class SessionController : Controller
{
    private readonly ISessionsService sessionService;

    public SessionController(ISessionsService sessionsService)
    {
        this.sessionService = sessionService;
    }

    public ActionResult SessionData(int sessionId)
    {
        var sessionData = sessionService.GetById(sessionId);

        /// do whatever validation you might require here

       var model = new SessionView(sessionData); // you could even pass the sessionId if required here

       return View(model);
    }
}

你可以将你的服务依赖注入到你的控制器中。我认为这是在 MVC 上执行此操作的首选方式

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-11
    • 2014-07-23
    • 2015-02-26
    • 2012-02-18
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    • 2021-11-14
    相关资源
    最近更新 更多