Шаблон настраиваемого поля динамических данных, обновляющий список - PullRequest
1 голос
/ 21 февраля 2011

У меня есть веб-сайт, использующий динамические данные и linq to sql. Этот веб-сайт работает с 3 «дочерними сайтами» и содержит список категорий, имеющих отношение «многие ко многим».

У меня есть 3 таблицы и, следовательно, 3 объекта в моем dbml; Веб-сайт, категории и категорииТу-сайты

Я пытаюсь создать шаблон поля так, чтобы на моей странице Categories / Edit.aspx я мог редактировать категорию и указывать, к какому веб-сайту относится категория.

Шаблон поля - CategoriesToWebsites_Edit.ascx, который представляет собой список флажков, привязанный к списку веб-сайтов.

Код ниже:

public partial class CategoriesToWebsitesEdit : FieldTemplateUserControl
{
    protected override void OnLoad(EventArgs e)
    {
        var dataSource = (LinqDataSource)this.FindDataSourceControl();

        dataSource.Inserting += OnInserting;
        dataSource.Updating += OnUpdating;
    }

    private void OnUpdating(object sender, LinqDataSourceUpdateEventArgs e)
    {
        var newCategory = (Category)e.NewObject;
        var oldCategory = (Category)e.OriginalObject;

        foreach(var listItem in WebsiteList.Items.Cast<ListItem>())
        {
            //check if website category already exists
            var categoryToWebsite = oldCategory.CategoriesToWebsites.FirstOrDefault(x => x.WebsiteId == Convert.ToInt32(listItem.Value));

            //website category exists
            if (categoryToWebsite != null)
            {
                // check if selected for removal, remove
                if (!listItem.Selected)
                {
                    newCategory.CategoriesToWebsites.Remove(categoryToWebsite);
                }
            }

            //we want to insert
            if (listItem.Selected)
            {
                //website category does not exist, add
                if (categoryToWebsite == null)
                {
                    //add selected website if not already exists
                    newCategory.CategoriesToWebsites.Add(new CategoriesToWebsite
                    {
                        WebsiteId = Convert.ToInt32(listItem.Value)
                    });
                }
            }


        }
    }

    private void OnInserting(object sender, LinqDataSourceInsertEventArgs e)
    {
        var category = (Category)e.NewObject;

        foreach(var listItem in WebsiteList.Items.Cast<ListItem>())
        {
            if(!listItem.Selected)
                continue;

            category.CategoriesToWebsites.Add(new CategoriesToWebsite
            {
                WebsiteId = Convert.ToInt32(listItem.Value)
            });
        }
    }

    protected override void OnDataBinding(EventArgs e)
    {
        var websiteRepository = new WebsiteRepository();
        var websites = websiteRepository.GetAll();

        var websiteCategories = (IEnumerable<CategoriesToWebsite>)FieldValue;

        foreach(var website in websites)
        {
            var currentWebsite = website;

            var listItem = new ListItem(website.Name, website.Id.ToString())
            {
                Selected = websiteCategories == null ? false : websiteCategories.Any(w => w.WebsiteId == currentWebsite.Id)
            };

            WebsiteList.Items.Add(listItem);
        }
    }
}

Когда я захожу в Categories / Insert.aspx, чтобы создать новую категорию, она проходит через код OnInserting и сохраняет его в db просто отлично, здесь все работает.

На Categories / Edit.aspx он проходит код, как я и ожидал, но, похоже, ничего не сохраняет.

Чего мне не хватает? - Я не слишком знаком с динамическими шаблонами полей данных, поэтому любые рекомендации будут высоко оценены

1 Ответ

1 голос
/ 22 февраля 2011

Видимо, я немного ошибался. Я просто обновлял объект в источнике данных linq, который не был сохранен. Поэтому вместо этого я иду прямо в хранилище:

private void OnUpdating(object sender, LinqDataSourceUpdateEventArgs e)
    {
        var newCategory = (Category)e.NewObject;
        var oldCategory = (Category)e.OriginalObject;

        var repository = new Repository<CategoriesToWebsite>();

        var ctw = repository.GetAll().Where(x => x.CategoryId == newCategory.Id);

        foreach (var listItem in WebsiteList.Items.Cast<ListItem>())
        {
            var current = ctw.FirstOrDefault(x => x.WebsiteId == Convert.ToInt32(listItem.Value));

            //current categoriesToWebsite exists
            if (current != null)
            {
                //if not selected, remove
                if (!listItem.Selected)
                    repository.Delete(current);
            }

            //does not exist
            else
            {
                //if selected, add
                if (listItem.Selected)
                    repository.Save(new CategoriesToWebsite()
                        {
                            CategoryId = newCategory.Id,
                            WebsiteId = Convert.ToInt32(listItem.Value)
                        }
                    );
            }
        }

        UnitOfWork.Current.SubmitChanges();
    }

Я не уверен, что это правильный способ сделать это, поскольку шаблон поля здесь выполняет некоторые обновления непосредственно в БД. Но это работает.

...