Linq для пользовательского объекта массива - PullRequest
2 голосов
/ 17 июня 2011

Я использую MVC3 / Entity Framework, мне нужно отправить объект JSON для использования jsTree. JsTree вызывает дочерние элементы каждый раз, когда расширяется узел, поэтому каждый метод get возвращает только один набор вместо всего дерева. Это функция get:

public ActionResult GetTreeview(string id, string company)
    {
        int parentId = Convert.ToInt32(id);
        var cats = (from x in db.Categories where x.ICG_PARENT_ID == parentId orderby x.ICG_CATEGORY_NAME select new { x.ICG_CATEGORY_ID, x.ICG_PARENT_ID, x.ICG_CATEGORY_NAME }).ToList();
        var jsTree = new JsTreeModel[cats.Count];

        for (int i = 0; i < cats.Count; i++)
        {
            jsTree[i] = new JsTreeModel
            {
            data = cats[i].ICG_CATEGORY_NAME, 
            attr = new JsTreeAttribute { id = cats[i].ICG_CATEGORY_ID }, 
            state = "closed"
            };
        }

        return Json(jsTree, JsonRequestBehavior.AllowGet);
    }

и вот модель:

public class JsTreeModel
{
    public string data;
    public string state;
    public JsTreeAttribute attr;
}

public class JsTreeAttribute
{
    public int id;
    public bool selected;
}

Я уверен, что более короткий / лучший способ сделать это должен существовать, но я только недавно начал изучать LINQ и лямбда-выражения (и MVC), и они пока не совсем понятны для меня. Кроме того, я давно использую этот сайт в качестве ресурса (это замечательно), но это мой первый вопрос. Действительно ли нет кнопки предварительного просмотра, или я слепой?

EDIT: обновлены модель и функция, чтобы изменить тип attr.Id на int. LINQ to Entities не понравилось преобразование строк.

Ответы [ 2 ]

2 голосов
/ 17 июня 2011

Simple:

public ActionResult GetTreeview(string id, string company)
{
    // company is not being used...
    var parentId = Convert.ToInt32(id);
    var jsTree =
        (from category in db.Categories
         where category.ICG_PARENT_ID == parentId
         orderby category.ICG_CATEGORY_NAME
         select new JsTreeModel
         {
             data = category.ICG_CATEGORY_NAME,
             attr = new JsTreeAttribute { id = category.ICG_CATEGORY_ID.ToString() },
             state = "closed",
         }).ToArray();

    return Json(jsTree, JsonRequestBehavior.AllowGet);
}


Для условного предложения where вы можете сделать это несколькими способами, и они не будут иметь большого значения в этом изолированном примере.Вы можете либо условно использовать один из двух запросов с предложением where:
JsTreeModel[] jsTree;
if (parentId == 0)
{
    var companyId = Convert.ToInt32(company);
    jsTree = (from category in db.Categories
              where category.ICG_PARENT_ID == parentId
                 && category.ICG_COMPANY_ID == companyId
              //etc...
             ).ToList();

}
else
{

    jsTree = (from category in db.Categories
              where category.ICG_PARENT_ID == parentId
              //etc..
             ).ToList();
}

Или вы можете разорвать запрос там, где вы вставили бы предложение where, условно добавить дополнительное предложение и завершить запрос:

// get the first part of the query
IQueryable<Category> query = db.Categories
    .Where(category => category.ICG_PARENT_ID == parentId);

// conditionally add the where clause
if (parentId == 0)
{
    var companyId = Convert.ToInt32(company);
    query = query.Where(category => category.ICG_COMPANY_ID == companyId);
}

// finish the query
var jsTree = query
    .OrderBy(category => category.ICG_CATEGORY_NAME)
    .AsEnumerable() // use LINQ to Objects from this point on
    .Select(category => new JsTreeModel
     {
         data = category.ICG_CATEGORY_NAME,
         attr = new JsTreeAttribute { id = category.ICG_CATEGORY_ID.ToString() },
         state = "closed",
     }).ToArray();
0 голосов
/ 17 июня 2011

Попробуйте:

var jsTree = (from cat in cats
             select new JsTreeModel
             {
                 data = cat.ICG_CATEGORY_NAME, 
                 attr = new JsTreeAttribute { id = cat.ICG_CATEGORY_ID.ToString() }, 
                 state = "closed"
             }).ToArray();
...