Issue extending the base EDMX model and calling the functions in the data model

懵懂的女人 提交于 2019-12-23 04:45:23

问题


I am writing a solution using MVC with scaffolding. It uses Entity Framework v6 and is database first in design. The base data model (ServiceAccountFilter) is extended by the data model (FilterModel). There is some logic in the FilterModel but the properties are all inherited from the base model. It seems as though the controller insists on using the base model. When I change the return to use the FilterModel, I get an error that the view requires the base model and then the functions in the FilterModel are not visible in the views? Not sure how to handle this?

Base Model:

 namespace FHN.ARX.AdminWeb
    {
        using System;
        using System.Collections.Generic;
        using System.ComponentModel;

        public partial class ServiceAccountFilter
        {
            [DisplayName("Filter ID")]
            public virtual int FilterId { get; set; }
            [DisplayName("Filter Name")]
            public virtual string FilterName { get; set; }
            [DisplayName("Service Account")]
            public virtual string ServiceAccount { get; set; }
            [DisplayName("Doc Type")]
            public virtual string DocType { get; set; }
            [DisplayName("Doc Type ID")]
            public virtual Nullable<int> DocTypeId { get; set; }
            [DisplayName("Doc Name ID")]
            public virtual string DocNameId { get; set; }
            [DisplayName("Last Modified By ID")]
            public virtual string LastModifiedById { get; set; }
            [DisplayName("Last Modified By")]
            public virtual string LastModifiedByName { get; set; }
            [DisplayName("Last Modified")]
            public virtual Nullable<System.DateTime> LastModified { get; set; }
            [DisplayName("Months To Return")]
            public virtual Nullable<int> MonthsToReturn { get; set; }
        }
    }

FilterModel

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace FHN.ARX.AdminWeb.Models
{
    public class FilterModel : ServiceAccountFilter
    {
        [DisplayName("Filter ID")]
        public override int FilterId { get; set; }
        [DisplayName("Filter Name")]
        public override string FilterName { get; set; }
        [DisplayName("Service Account")]
        public override string ServiceAccount { get; set; }
        [DisplayName("Doc Type")]
        public override string DocType { get; set; }
        [DisplayName("Doc Type ID")]
        public override Nullable<int> DocTypeId { get; set; }
        [DisplayName("Doc Name ID")]
        public override string DocNameId { get; set; }
        [DisplayName("Last Modified By ID")]
        public override string LastModifiedById { get; set; }
        [DisplayName("Last Modified By")]
        public override string LastModifiedByName { get; set; }
        [DisplayName("Last Modified")]
        public override Nullable<System.DateTime> LastModified { get; set; }
        [DisplayName("Months To Return")]
        public override Nullable<int> MonthsToReturn { get; set; }
        public bool Selected { get; set; }
        public string Checkboxes { get; set; }

        public IEnumerable<SelectListItem> DocTypesList(string id)
        {
            using (var db = new ARXEntities())
            {
                var docType = new List<SelectListItem>();
                docType = (from t in db.vwMapDocNamesToSecurityUsers
                           where t.UserDN == id
                           orderby t.DocType
                           select new { t.DocType, t.DocTypeId }).Distinct().Select(x => new SelectListItem() { Text = x.DocType, Value = x.DocTypeId.ToString() }).OrderBy(x => x.Text).ToList();
                return docType;
            }
        }

        public IEnumerable<SelectListItem> DocNamesList()
        {
            using (var db = new ARXEntities())
            {
                IEnumerable<SelectListItem> docName = new List<SelectListItem>();
                var loggedInUser = "C2693"; // HttpContext.Current.User.Identity.Name.Split('\\')[1];
                docName = (from t in db.vwMapDocNamesToSecurityUsers
                           where t.UserDN == loggedInUser
                           select new { t.DocName, t.DocNameId, t.DocTypeId }).Distinct().Select(x => new SelectListItem()
                           {
                               Text = x.DocName,
                               Value = x.DocNameId.ToString(),
                               Group = new SelectListGroup() { Name = x.DocTypeId.ToString() }
                           }).Distinct().OrderBy(x => x.Text).ToList();
                var docCount = docName.Count();
                return docName;
            }
        }

        public IEnumerable<SelectListItem> ServiceAccountList()
        {
            using (var db = new ARXEntities())
            {
                var sa = new List<SelectListItem>();
                sa = (from t in db.vwMapDocNamesToSecurityUsers
                      where t.UserDN.StartsWith("sa_")
                      orderby t.UserDN
                      select new { t.UserDN }).Distinct().Select(x => new SelectListItem() { Text = x.UserDN, Value = x.UserDN }).OrderBy(x => x.Text).ToList();
                return sa;
            }
        }

        public IEnumerable<SelectListItem> DocNamesByDocTypeIdList()
        {
            using (var db = new ARXEntities())
            {
                IEnumerable<SelectListItem> docName = new List<SelectListItem>();
                docName = (from t in db.vwMapDocNamesToSecurityUsers
                           select new { t.DocName, t.DocNameId, t.DocTypeId }).Distinct().Select(x => new SelectListItem()
                           {
                               Text = x.DocName,
                               Value = x.DocNameId.ToString(),
                               Group = new SelectListGroup() { Name = x.DocTypeId.ToString() }
                           }).Distinct().OrderBy(x => x.Text).ToList();
                var docCount = docName.Count();
                return docName;
            }
        }

        public IEnumerable<SelectListItem> GetDocNamesForFilterId(int? id)
        {
            using (var db = new ARXEntities())
            {
                IEnumerable<SelectListItem> docName = new List<SelectListItem>();
                docName = (from t in db.ServiceAccountFilters
                           where t.FilterId == id
                           select new { t.DocNameId, t.FilterId }).Distinct().Select(x => new SelectListItem()
                           {
                               Text = x.DocNameId,
                               Value = x.DocNameId.ToString(),
                               Group = new SelectListGroup() { Name = x.DocNameId.ToString() }
                           }).Distinct().OrderBy(x => x.Text).ToList();
                return docName;
            }
        }
    }
}

Controller Edit Action

 public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                var saf = new FilterModel();
                return View(saf);
            }
            FilterModel serviceAccountFilter = (FilterModel)db.ServiceAccountFilters.Find(id); <----Tried casting here, but still didnt work.
            if (serviceAccountFilter == null)
            {
                return HttpNotFound();
            }
            return View(serviceAccountFilter);
        }

Edit View

@model FHN.ARX.AdminWeb.Models.FilterModel

@{
    ViewBag.Title = "Edit A Filter";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="pageTitle">Filter Maintenance</div>


@using (Html.BeginForm(new { id = "filterForm" }))
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.FilterId)
        @Html.HiddenFor(model => model.LastModified)
        @Html.HiddenFor(model => model.LastModifiedById)
        @Html.HiddenFor(model => model.LastModifiedByName)

        <div class="ddlGroups, btmMarg-15">
            @Html.DropDownListFor(m => m.ServiceAccount, Model.ServiceAccountList(), "Select a Service Account")
        </div>
        <div class="ddlGroups, col-md-10, btmMarg-15">
            @Html.LabelFor(model => model.ServiceAccount, htmlAttributes: new { @class = "control-label col-md-2" })
            @Html.EditorFor(model => model.ServiceAccount, new { htmlAttributes = new { @class = "form-control" } })
        </div>
        <div class="ddlGroups, col-md-10, btmMarg-15">
            @Html.LabelFor(model => model.DocTypeId, htmlAttributes: new { @class = "control-label col-md-2" })
            @Html.EditorFor(model => model.DocTypeId, new { htmlAttributes = new { @class = "form-control" } })
        </div>
        <p class="leftMarg-15 text-default" id="docNamesHdrText">Select the document names to be included in the filter.</p>
        <div class="ckDocNames">
            @foreach (var dn in Model.DocNamesByDocTypeIdList())
            {
                <div class="checkboxContainer">
                    <input class="ckBoxes" type="checkbox" name="DocNameId" value="@dn.Value" dtid="@dn.Group.Name" />@dn.Text<br />
                </div>
            }
        </div>
        <div class="form-group, col-md-10, btmMarg-15" id="monthsGroup">
            @Html.LabelFor(model => model.MonthsToReturn, htmlAttributes: new { @class = "control-label col-md-2" })
            @Html.EditorFor(model => model.MonthsToReturn, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.MonthsToReturn, "", new { @class = "text-danger" })
        </div>
        <div class="form-group, col-md-10, btmMarg-15" id="filterNameGroup">
            @Html.LabelFor(model => model.FilterName, htmlAttributes: new { @class = "control-label col-md-2" })
            @Html.EditorFor(model => model.FilterName, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.FilterName, "", new { @class = "text-danger" })
        </div>


        <br />
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" id="modSaveButton" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "ActiveFilters")  |
    @Html.ActionLink("Admin Home", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

回答1:


this is an example of using a viewmodel on your case ... (may be it's not prefect but just a hint on your way)

namespace FHN.ARX.AdminWeb
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;

    public partial class ServiceAccountFilter
    {
        public int FilterId { get; set; }
        public string FilterName { get; set; }
        public string ServiceAccount { get; set; }
        public string DocType { get; set; }
        public Nullable<int> DocTypeId { get; set; }
        public string DocNameId { get; set; }
        public string LastModifiedById { get; set; }
        public string LastModifiedByName { get; set; }
        public Nullable<System.DateTime> LastModified { get; set; }
        public Nullable<int> MonthsToReturn { get; set; }
    }
}

no need for the filter model now and instead of that put all the logic in the controller under a heper region

#region Helpers

public IEnumerable<SelectListItem> DocTypesList(string id)
{
    using (var db = new ARXEntities())
    {
        var docType = new List<SelectListItem>();
        docType = (from t in db.vwMapDocNamesToSecurityUsers
                    where t.UserDN == id
                    orderby t.DocType
                    select new { t.DocType, t.DocTypeId }).Distinct().Select(x => new SelectListItem() { Text = x.DocType, Value = x.DocTypeId.ToString() }).OrderBy(x => x.Text).ToList();
        return docType;
    }
}

public IEnumerable<SelectListItem> DocNamesList()
{
    using (var db = new ARXEntities())
    {
        IEnumerable<SelectListItem> docName = new List<SelectListItem>();
        var loggedInUser = "C2693"; // HttpContext.Current.User.Identity.Name.Split('\\')[1];
        docName = (from t in db.vwMapDocNamesToSecurityUsers
                    where t.UserDN == loggedInUser
                    select new { t.DocName, t.DocNameId, t.DocTypeId }).Distinct().Select(x => new SelectListItem()
                    {
                        Text = x.DocName,
                        Value = x.DocNameId.ToString(),
                        Group = new SelectListGroup() { Name = x.DocTypeId.ToString() }
                    }).Distinct().OrderBy(x => x.Text).ToList();
        var docCount = docName.Count();
        return docName;
    }
}

public IEnumerable<SelectListItem> ServiceAccountList()
{
    using (var db = new ARXEntities())
    {
        var sa = new List<SelectListItem>();
        sa = (from t in db.vwMapDocNamesToSecurityUsers
                where t.UserDN.StartsWith("sa_")
                orderby t.UserDN
                select new { t.UserDN }).Distinct().Select(x => new SelectListItem() { Text = x.UserDN, Value = x.UserDN }).OrderBy(x => x.Text).ToList();
        return sa;
    }
}

public IEnumerable<SelectListItem> DocNamesByDocTypeIdList()
{
    using (var db = new ARXEntities())
    {
        IEnumerable<SelectListItem> docName = new List<SelectListItem>();
        docName = (from t in db.vwMapDocNamesToSecurityUsers
                    select new { t.DocName, t.DocNameId, t.DocTypeId }).Distinct().Select(x => new SelectListItem()
                    {
                        Text = x.DocName,
                        Value = x.DocNameId.ToString(),
                        Group = new SelectListGroup() { Name = x.DocTypeId.ToString() }
                    }).Distinct().OrderBy(x => x.Text).ToList();
        var docCount = docName.Count();
        return docName;
    }
}

public IEnumerable<SelectListItem> GetDocNamesForFilterId(int? id)
{
    using (var db = new ARXEntities())
    {
        IEnumerable<SelectListItem> docName = new List<SelectListItem>();
        docName = (from t in db.ServiceAccountFilters
                    where t.FilterId == id
                    select new { t.DocNameId, t.FilterId }).Distinct().Select(x => new SelectListItem()
                    {
                        Text = x.DocNameId,
                        Value = x.DocNameId.ToString(),
                        Group = new SelectListGroup() { Name = x.DocNameId.ToString() }
                    }).Distinct().OrderBy(x => x.Text).ToList();
        return docName;
    }
}

#endregion

in your controller Edit Action

public ActionResult Edit(int? id)
{
    if (id == null)
    {
        var saf = new FilterModel();
        return View(saf);
    }
    var serviceAccountFilter = db.ServiceAccountFilters.Find(id)
    if (serviceAccountFilter == null)
    {
        return HttpNotFound();
    }

    var model = new FilterViewModel 
    {
        FilterId = serviceAccountFilter.FilterId,
        FilterName = serviceAccountFilter.FilterName,
        ServiceAccount = serviceAccountFilter.ServiceAccount,
        DocType = serviceAccountFilter.DocType,
        DocTypeId = serviceAccountFilter.DocTypeId,
        DocNameId = serviceAccountFilter.DocNameId,
        LastModifiedById = serviceAccountFilter.LastModifiedById,
        LastModifiedByName = serviceAccountFilter.LastModifiedByName,
        LastModified = serviceAccountFilter.LastModified,
        MonthsToReturn = serviceAccountFilter.MonthsToReturn,
        ServiceAccountList = ServiceAccountList(),
        DocNamesByDocTypeIdList = DocNamesByDocTypeIdList()
    };

    return View(model);
}

and here is a ViewModel lets say it's name will be FilterViewModel

public class FilterModel
{
    [DisplayName("Filter ID")]
    public int FilterId { get; set; }
    [DisplayName("Filter Name")]
    public string FilterName { get; set; }
    [DisplayName("Service Account")]
    public string ServiceAccount { get; set; }
    [DisplayName("Doc Type")]
    public string DocType { get; set; }
    [DisplayName("Doc Type ID")]
    public Nullable<int> DocTypeId { get; set; }
    [DisplayName("Doc Name ID")]
    public string DocNameId { get; set; }
    [DisplayName("Last Modified By ID")]
    public string LastModifiedById { get; set; }
    [DisplayName("Last Modified By")]
    public string LastModifiedByName { get; set; }
    [DisplayName("Last Modified")]
    public Nullable<System.DateTime> LastModified { get; set; }
    [DisplayName("Months To Return")]
    public Nullable<int> MonthsToReturn { get; set; }

    public IEnumerable<SelectListItem> ServiceAccountList { get; set; }
    public IEnumerable<SelectListItem> DocNamesByDocTypeIdList { get; set; }
}

and then your Edit View will be

@model FilterViewModel // check the name space

@{
    ViewBag.Title = "Edit A Filter";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="pageTitle">Filter Maintenance</div>


@using (Html.BeginForm(new { id = "filterForm" }))
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.FilterId)
        @Html.HiddenFor(model => model.LastModified)
        @Html.HiddenFor(model => model.LastModifiedById)
        @Html.HiddenFor(model => model.LastModifiedByName)

        <div class="ddlGroups, btmMarg-15">
            @Html.DropDownListFor(m => m.ServiceAccount, Model.ServiceAccountList(), "Select a Service Account")
        </div>
        <div class="ddlGroups, col-md-10, btmMarg-15">
            @Html.LabelFor(model => model.ServiceAccount, htmlAttributes: new { @class = "control-label col-md-2" })
            @Html.EditorFor(model => model.ServiceAccount, new { htmlAttributes = new { @class = "form-control" } })
        </div>
        <div class="ddlGroups, col-md-10, btmMarg-15">
            @Html.LabelFor(model => model.DocTypeId, htmlAttributes: new { @class = "control-label col-md-2" })
            @Html.EditorFor(model => model.DocTypeId, new { htmlAttributes = new { @class = "form-control" } })
        </div>
        <p class="leftMarg-15 text-default" id="docNamesHdrText">Select the document names to be included in the filter.</p>
        <div class="ckDocNames">
            @foreach (var dn in Model.DocNamesByDocTypeIdList())
            {
                <div class="checkboxContainer">
                    <input class="ckBoxes" type="checkbox" name="DocNameId" value="@dn.Value" dtid="@dn.Group.Name" />@dn.Text<br />
                </div>
            }
        </div>
        <div class="form-group, col-md-10, btmMarg-15" id="monthsGroup">
            @Html.LabelFor(model => model.MonthsToReturn, htmlAttributes: new { @class = "control-label col-md-2" })
            @Html.EditorFor(model => model.MonthsToReturn, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.MonthsToReturn, "", new { @class = "text-danger" })
        </div>
        <div class="form-group, col-md-10, btmMarg-15" id="filterNameGroup">
            @Html.LabelFor(model => model.FilterName, htmlAttributes: new { @class = "control-label col-md-2" })
            @Html.EditorFor(model => model.FilterName, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.FilterName, "", new { @class = "text-danger" })
        </div>


        <br />
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" id="modSaveButton" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "ActiveFilters")  |
    @Html.ActionLink("Admin Home", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}


来源:https://stackoverflow.com/questions/33246684/issue-extending-the-base-edmx-model-and-calling-the-functions-in-the-data-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!