【问题标题】:how to iterate through an Icollection In MVC3 nhibernate如何在 MVC3 nhibernate 中遍历 Icollection
【发布时间】:2012-04-25 12:54:47
【问题描述】:

我正在 mvc3 中开发一个应用程序。
我有两个下拉列表,并根据在第一个下拉列表中选择的值填充第二个下拉列表。 第一个下拉菜单是课程,根据选择的课程,第二个下拉菜单会填充课程可用的状态。

例如,如果课程是“MCA”,则州应该是马哈拉施特拉邦、拉贾斯坦邦等。 为此,我编写了一个运行良好的 ajax 函数。 但问题是我无法一次获取多个状态,即我一次只能获取一个状态。

我编写了以下代码来获取状态名称:

HobbyHomeAdress 表包含我通过其他方法获取的ProvincialStateID。 然后我将该值与ProvincialState 表中ProvincialStateID 中的值进行比较,并获取该表的数据,但它只给了我最后一条记录。

 public ICollection<ProvincialState> FetchStateByStateid(ICollection<HobbyHomeAddress> hobbyhomeaddresslist)
    {
        log.Debug("Start");
        ISession session = DataAccessLayerHelper.OpenWriterSession();
        ITransaction transaction = session.BeginTransaction();
        ICollection<ProvincialState> provincialstate = null;
        try
        {
            foreach (var state in hobbyhomeaddresslist)
            {
                provincialstate = session.CreateCriteria(typeof(ProvincialState))
                                .Add(Expression.Eq("ProvincialStateID", state.ProvincialState.ProvincialStateID))
                                .List<ProvincialState>();
            }
            transaction.Commit();

        }
        catch (SessionException ex)
        {
            if (transaction != null && transaction.IsActive)
                transaction.Rollback();

            log.Error(ex);
            provincialstate = null;
        }
        finally
        {
            if (transaction != null)
                transaction.Dispose();

            if (session != null && session.IsConnected)
                session.Close();

            log.Debug("End");
        }
        return provincialstate;
    }

【问题讨论】:

    标签: asp.net-mvc-3 model-view-controller nhibernate drop-down-menu


    【解决方案1】:

    您正在为 hobbyhomeaddresslist 中的每个州重新创建省级集合。因此,您最终会得到一个包含单个条目的集合,通常是最后一个条目。相反,您应该先创建集合,然后在检索项目后将其添加到该集合中。

    ...剪辑

        ...
        List<ProvincialState> provincialstate = new List<ProvincialState>();
        try
        {
            foreach (var state in hobbyhomeaddresslist)
            {
    
                var list = session.CreateCriteria(typeof(ProvincialState))
                                .Add(Expression.Eq("ProvincialStateID",       state.ProvincialState.ProvincialStateID))
                                .List<ProvincialState>();
                provincialstate.AddRange(list);
            }
            transaction.Commit();
    
        }
        ...
    

    更新:使用析取的单个查询。

        IList<ProvincialState> provincialstate = null;
        Disjunction dj = new Disjunction();    
        try
        {
            foreach (var state in hobbyhomeaddresslist)
            {
                dj.Add(Expression.Eq("ProvincialStateID",       state.ProvincialState.ProvincialStateID));
            }
            provincialstate = session.CreateCriteria(typeof(ProvincialState))
                           .Add(dj)
                           .List<ProvincialState>();
    
            transaction.Commit();
    
        }
    

    如果您查看生成的 SQL,您现在应该会看到带有多个 where 子句的单个 select,而不是带有单个 where 子句的多个 select。

    【讨论】:

    • thanx 4 回复我理解你的解释,但我没有得到任何功能,因为 'AddRange()' 必须为它添加一些东西吗??
    • 你确实意识到这是在找一个 n+1 查询的麻烦
    • @user1274646:你是否将省级状态的定义从 ICollection 更改为 List? ICollection 没有 AddRange,List 有。而 List 实现了 ICollection,因此您可以将 List 作为 ICollection 返回。
    • @GarlandGreene 是的,我改变了它...IListprovincialstate = new List();但我还是写了省级状态.AddRange(list) 它不认识它。我得到的只是 Add() 我可以用它来代替这个吗???
    • 不是 IList,List。但由于您目前一次只加载一个项目,您也可以使用 Add() 添加该单个项目。您还可以一次加载所有项目,在 Disjunction 中使用多个 EqExpression(NHibernate Criteria API 等效于 OR)。这样,您将获得一个集合并且只有一个选择。这也将绕过 Baz1nga 提到的问题。
    猜你喜欢
    • 1970-01-01
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-28
    • 2012-06-07
    相关资源
    最近更新 更多