C# 如何扩展模型以填充网格,而不在保存时验证外键?

C# 如何扩展模型以填充网格,而不在保存时验证外键?,c#,entity-framework,model-view-controller,telerik,C#,Entity Framework,Model View Controller,Telerik,我们有一个设计范例,我们正在考虑标准化,但它有一些问题,我们没有一个很好的解决方案 1) 我们创建一个核心模型,其中包含所有外键的常规字段和索引值。这是绑在一个表,在我们的设计将在我们的网格弹出编辑 2) 第二个类继承第一个类并具有所有外键引用。此类将填充网格。这将允许我们显示来自外部表的特定信息 现在解决问题:弹出模型必须与网格模型匹配(我们使用的是telerik网格),并且在保存时,EF尝试验证通过外键远程连接到表的任何内容,以及通过外键引用的任何内容。我们曾经有一个记录抛出错误,因为我们试

我们有一个设计范例,我们正在考虑标准化,但它有一些问题,我们没有一个很好的解决方案

1) 我们创建一个核心模型,其中包含所有外键的常规字段和索引值。这是绑在一个表,在我们的设计将在我们的网格弹出编辑

2) 第二个类继承第一个类并具有所有外键引用。此类将填充网格。这将允许我们显示来自外部表的特定信息

现在解决问题:弹出模型必须与网格模型匹配(我们使用的是telerik网格),并且在保存时,EF尝试验证通过外键远程连接到表的任何内容,以及通过外键引用的任何内容。我们曾经有一个记录抛出错误,因为我们试图编辑订单,而分配给订单驾驶员的卡车缺少里程信息

我尝试(成功地)用notmapped字段替换外键引用并将它们加载到索引文件中,但与EF相比速度较慢。我遍历了网格中的每个记录(每个记录),查找每个匹配的模型并添加它

另一个程序员绕过了这个问题,创建了两个完全不同的模型,让第二个模型的外键指向表的别名。我个人觉得这是违法的

我们的第三个开发人员做了类似的事情,但从视图中提取数据。事实上,他有一个很好的理由,因为该视图有一个基于财务结算的计算“锁定”列

好了。解决同一问题的三种不同方法。我也尝试过从帖子中“排除”,但我显然做错了

我们考虑过关闭EF中的验证,但没有人对它足够熟悉,知道它是否也会终止该页面上的验证。MVC是我们最近迈出的一步。我们的网站最初是asp。事实上,驱动力是我们的订单网格,这可能需要一分钟来加载

**所以在我给了你所有这些信息之后,这里有一个问题:*什么是建立我们模型的最佳方式?我是初级程序员,感觉我们在这三种情况下都做得不对。更重要的是,我觉得这完全没有必要。我想将一个模型绑定到一个网格,其中包含继承核心模型的完整数据,但这就是我们验证的全部内容。这是怎么做到的

控制器示例:

namespace DispatchCrude.Controllers
{
[Authorize(Roles = "viewShipperTimeCardWorkTypeRates")]
public class ShipperTimeCardWorkTypeRatesController : _DBController
{                      
    [HttpGet]
    public ActionResult Index(int? orderid, int? typeid)
    {
        // Send through any filters
        if (orderid != null)
            ViewBag.OrderID = orderid;

        if (typeid != null)
            ViewBag.TypeID = typeid;

        return View();
    }

    // Read
    [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
    virtual public ContentResult Read([DataSourceRequest] DataSourceRequest request = null, int id = 0, int? orderid = null)
    {
        return Read(request, null, id, orderid);
    }

    protected ContentResult Read([DataSourceRequest] DataSourceRequest request, ModelStateDictionary modelState, int id = 0, int? orderid = null)
    {
        var data = db.ShipperTimeCardWorkTypeRates
                    .Where(m => m.ID == id || id == 0).ToList();
        if (orderid != null)
        {
            var validRates = db.Database.SqlQuery<int>(@"SELECT R.ID
                    FROM dbo.viewOrder O
                    CROSS APPLY dbo.fnShipperTimeCardRates(isnull(O.OrderDate, O.DueDate), null, null,
                        O.TicketTypeID, O.DestTicketTypeID, O.CustomerID, CarrierTypeID, O.CarrierID, DriverGroupID, O.DriverID, O.TruckTypeID, O.ProductGroupID,
                        O.DestinationID, O.OriginID, O.DestStateID, O.OriginStateID, O.DestRegionID, O.OriginRegionID, O.ProducerID, 0) R
                    WHERE O.ID = " + orderid);
            data = data.Where(m => validRates.Contains(m.ID)).ToList();

        }
        return ToJsonResult(data, request, modelState);
    }

    // Create
    [HttpPost]
    [Authorize(Roles = "createShipperTimeCardWorkTypeRates")]
    public ActionResult Create([DataSourceRequest] DataSourceRequest request, ShipperTimeCardWorkTypeRateBase timeCardWorkTypeRates)
    {

        // Create functionality is now taken care of in the update function as of Kevin's 2017 update to how MVC controllers are written
        return Update(request, timeCardWorkTypeRates);  
    }

    // Update
    [HttpPost]
    [Authorize(Roles = "editShipperTimeCardWorkTypeRates")]
    public ActionResult Update([DataSourceRequest] DataSourceRequest request, ShipperTimeCardWorkTypeRateBase timeCardWorkTypeRates)
    {
        try
        {
            DateTime checkDate1;
            DateTime checkDate2;
            bool success1 = DateTime.TryParse(timeCardWorkTypeRates.EffectiveDate.ToString(), out checkDate1);
            bool success2 = DateTime.TryParse(timeCardWorkTypeRates.EndDate.ToString(), out checkDate2);
            if (success1 && success2 && checkDate2.Subtract(checkDate1).TotalHours < 0)
            {
                ModelState.AddModelError("Update", "End Date must be equal to or later than Start Date.");    
            }
            if (ModelState.IsValid)
            {
                // Create new record or update existing record
                db.AddOrUpdateSave(User.Identity.Name, timeCardWorkTypeRates);
            }
        }
        catch (Exception ex)
        {
            ModelState.AddModelError("Update", ex.Message); // TODO: use a common routine to "cleanup" db generated errors
            return App_Code.JsonStringResult.Create(new[] { timeCardWorkTypeRates }.ToDataSourceResult(request, ModelState));
        }
        return Read(request, ModelState, timeCardWorkTypeRates.ID);
    }

    // Delete (Deactivate)
    [HttpPost]
    [Authorize(Roles = "deleteShipperTimeCardWorkTypeRates")]
    public ActionResult Delete([DataSourceRequest] DataSourceRequest request, ShipperTimeCardWorkTypeRateBase shipperTimeCardWorkTypeRate)
    {
        // Delete the record
        db.ShipperTimeCardWorkTypeBases.Attach(shipperTimeCardWorkTypeRate);
        db.ShipperTimeCardWorkTypeBases.Remove(shipperTimeCardWorkTypeRate);
        db.SaveChanges(User.Identity.Name);

        return null;
    }

    public ContentResult getBestMatch(int orderid, int? typeid = null)
    {
        string sql = "SELECT DISTINCT ID FROM fnOrderShipperTimeCardRates(" + orderid + ")";
        if (typeid != null)
            sql += " WHERE WorkTypeID = " + typeid;

        var bestmatchids = db.Database.SqlQuery<int>(sql);
        return ToJsonResult(bestmatchids.ToList());
    }
}
namespace dispatchrough.Controllers
{
[授权(Roles=“viewShipperTimeCardWorkTypeRates”)]
公共类ShipperTimeCardWorkTypeRatesController:\u DBController
{                      
[HttpGet]
公共操作结果索引(int?orderid、int?typeid)
{
//通过任何过滤器发送
if(orderid!=null)
ViewBag.OrderID=OrderID;
if(typeid!=null)
ViewBag.TypeID=TypeID;
返回视图();
}
//阅读
[接受动词(HttpVerbs.Get | HttpVerbs.Post)]
虚拟公共ContentResult读取([DataSourceRequest]DataSourceRequest请求=null,int id=0,int?orderid=null)
{
返回读取(请求,null,id,orderid);
}
受保护的ContentResult读取([DataSourceRequest]DataSourceRequest请求,ModelStateDictionary modelState,int-id=0,int?orderid=null)
{
var data=db.ShipperTimeCardWorkTypeRates
.其中(m=>m.ID==ID | | ID==0).ToList();
if(orderid!=null)
{
var validRates=db.Database.SqlQuery(@“选择R.ID
从dbo.viewOrder
交叉应用dbo.fnShipperTimeCardRates(isnull(O.OrderDate,O.DueDate),null,null,
O.TicketTypeID、O.DestTicketTypeID、O.CustomerID、CarrierTypeID、O.CarrierID、DriverGroupID、O.DriverID、O.TruckTypeID、O.ProductGroupID、,
O.DestinationID、O.OriginID、O.DestStateID、O.OriginStateID、O.desregionId、O.OriginRegionID、O.ProducerID、0)R
其中O.ID=“+orderid”);
data=data.Where(m=>validRates.Contains(m.ID)).ToList();
}
返回JSONResult(数据、请求、模型状态);
}
//创造
[HttpPost]
[授权(Roles=“createShipperTimeCardWorkTypeRates”)]
公共操作结果创建([DataSourceRequest]DataSourceRequest请求,ShipperTimeCardWorkTypeRate基本timeCardWorkTypeRates)
{
//从Kevin 2017年更新MVC控制器的编写方式开始,创建功能现在在更新功能中得到了重视
返回更新(请求、timeCardWorkTypeRates);
}
//更新
[HttpPost]
[授权(Roles=“editShipperTimeCardWorkTypeRates”)]
公共操作结果更新([DataSourceRequest]DataSourceRequest请求,ShipperTimeCardWorkTypeRate基本timeCardWorkTypeRates)
{
尝试
{
日期时间检查日期1;
日期时间检查日期2;
bool success1=DateTime.TryParse(timeCardWorkTypeRates.EffectiveDate.ToString(),out checkDate1);
bool success2=DateTime.TryParse(timeCardWorkTypeRates.EndDate.ToString(),out checkDate2);
if(success1&&success2&&checkDate2.Subtract(checkDate1.TotalHours<0)
{
AddModelError(“更新”,“结束日期必须等于或晚于开始日期”);
}
if(ModelState.IsValid)
{
//创建新记录或更新现有记录
db.AddOrUpdateSave(User.Identity.Name,timeCardWorkTypeRates);
}
}
捕获(例外情况除外)
{
ModelState.AddModelError(“Update”,ex.Message);//TODO:使用公共例程“清理”db生成的错误
返回App_Code.JsonStringResult.Create(new[]{timeCardWorkTypeRates}.ToDataSourceResult(request,ModelState));
}