Asp.net mvc 约束实体框架中的子实体数 底线在前面

Asp.net mvc 约束实体框架中的子实体数 底线在前面,asp.net-mvc,entity-framework,collections,constraints,Asp.net Mvc,Entity Framework,Collections,Constraints,是否有一种简洁的方法可以限制实体框架中可以属于父实体的子实体的数量。目前我正在使用4.3.1 问题 我正在开发一个ASP.NET MVC3站点,它通过使用实体框架的数据访问层访问数据。我有一个SearchList实体,它与搜索实体有多对多关系。一个搜索列表可能有多个搜索,一个搜索可能属于多个搜索列表 在站点工作流的某一点上,用户需要选择要在批搜索中使用的搜索和其他项目。我们希望页面加载整个搜索列表 搜索列表可能会变得相当大,作为测试,我们创建了一个包含21000个搜索的列表。这花了几秒钟的时间,

是否有一种简洁的方法可以限制实体框架中可以属于父实体的子实体的数量。目前我正在使用4.3.1

问题 我正在开发一个ASP.NET MVC3站点,它通过使用实体框架的数据访问层访问数据。我有一个SearchList实体,它与搜索实体有多对多关系。一个搜索列表可能有多个搜索,一个搜索可能属于多个搜索列表

在站点工作流的某一点上,用户需要选择要在批搜索中使用的搜索和其他项目。我们希望页面加载整个搜索列表

搜索列表可能会变得相当大,作为测试,我们创建了一个包含21000个搜索的列表。这花了几秒钟的时间,返回的数据大约是9.5MB,这是我们所期望的,但是jQueryUI在尝试将数据表化到这么大的程度时被阻塞了

我们想要什么 因此,我们希望对任何搜索列表可以进行的搜索数量施加限制。我可以浏览应用程序并在其中放入一组规则,检查集合的大小,以及尝试添加的搜索是否加上当前集合的大小。。。雅达雅达雅达

但是,如果有更好的方法(特别是可以轻松输出MVC会接收到的错误消息的方法),我会完全采用这种方法

我已经在谷歌上搜索过,并且阅读过很多英孚的博客,但都没有用。集合和类似搜索中的约束子项和最大子项数返回了有关Linq查询以及Count和max方法的结果


任何帮助都将不胜感激。

没有内置的方法,因此您必须自己编写验证代码。一些快速的想法:

  • 例如,您可以对导航属性使用自定义集合,当您尝试添加超出阈值的其他搜索时,该属性将引发异常。它很简单,但它要求您加载所有搜索,它将有并发问题,而且它可以在加载搜索列表和数据库中的搜索时触发
  • 您可以在覆盖的
    SaveChanges
    中处理它。您至少需要检查有多少搜索已经与搜索列表相关,但您仍然存在并发问题(如果其他请求尝试将搜索添加到同一列表,但只剩下一个位置,则会怎样?这两个请求都可以成功检查并插入相关搜索)
  • 您可以在数据库触发器中处理它-同样,它会有并发问题

要完全避免并发问题,需要手动编写带有锁定提示的查询,以确保只有一个请求可以检查每个搜索列表的搜索数量,并在atomic transaction中插入新的搜索。

没有内置方式,因此您必须自己编写此类验证代码。一些快速的想法:

  • 例如,您可以对导航属性使用自定义集合,当您尝试添加超出阈值的其他搜索时,该属性将引发异常。它很简单,但它要求您加载所有搜索,它将有并发问题,而且它可以在加载搜索列表和数据库中的搜索时触发
  • 您可以在覆盖的
    SaveChanges
    中处理它。您至少需要检查有多少搜索已经与搜索列表相关,但您仍然存在并发问题(如果其他请求尝试将搜索添加到同一列表,但只剩下一个位置,则会怎样?这两个请求都可以成功检查并插入相关搜索)
  • 您可以在数据库触发器中处理它-同样,它会有并发问题

要完全避免并发问题,需要使用带有锁定提示的手写查询,以确保只有一个请求可以检查每个搜索列表的搜索数量,并在原子事务中插入新的搜索。

我最终选择了CustomValidationAttribute,并成功地实现了它。有关我的实施信息,请参见下文:

在SearchList实体中
[未映射]
公共字符串验证消息{get;set;}
[CustomValidation(typeof(EntityValidation.EntityValidators),“ValidateSearchCount”)]
公共虚拟列表搜索{get;set;}
公共静态bool创建(ProjectContext数据库,SearchList SearchList)
{
尝试
{
db.searchList.Add(searchList);
db.SaveChanges();
返回true;
}
catch(DbEntityValidationException dbEx)
{
foreach(dbEx.EntityValidationErrors中的var validationErrors)
{
foreach(validationErrors.validationErrors中的var validationError)
{
searchList.ValidationMessage+=validationError.ErrorMessage;
}
}
返回false;
}
捕获(例外)
{
返回false;
}
}
EntityValidators类
publicstaticvalidationresult ValidateSearchCount(列表搜索)
{
bool是有效的;
int count=Searches.count();

isValid=(count我最终使用了CustomValidationAttribute,并成功地实现了它。有关我的实现信息,请参见下面的内容:

在SearchList实体中
[未映射]
公共字符串验证消息{get;set;}
[CustomValidation(typeof(EntityValidation.EntityValidators),“ValidateSearchCount”)]
公共虚拟列表搜索{get;set;}
公共静态bool创建(ProjectContext数据库,SearchList SearchList)
{
尝试
{
db.searchList.Add(searchList);
db.SaveChanges();
返回true;
}
catch(DbEntityValidationException dbEx)
{
foreach(dbEx.EntityValidationErrors中的var validationErrors)
{
foreach(validationErrors.validationErrors中的var validationError)
{
    [NotMapped]
    public String ValidationMessage { get; set; }
    [CustomValidation(typeof(EntityValidation.EntityValidators), "ValidateSearchCount")]
    public virtual List<Search> Searches { get; set; }

    public static bool Create(ProjectContext db, SearchList searchList)
    {
        try
        {
            db.SearchLists.Add(searchList);
            db.SaveChanges();
            return true;
        }
        catch (DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {
                    searchList.ValidationMessage += validationError.ErrorMessage;
                }
            }
            return false;
        }
        catch (Exception)
        {
            return false;
        }
    }
    public static ValidationResult ValidateSearchCount(List<Search> Searches)
    {
        bool isValid;
        int count = Searches.Count();
        isValid = (count <= 5000 ? true : false);

        if (isValid)
        {
            return ValidationResult.Success;
        }
        else
        {
            return new ValidationResult("A maximum of 5000 searches may be added to a SearchList.");
        }
    }