Linq To Sql Много-много Join Table

Я - несколько опытный Rails-разработчик, и я подумал, что попробую ASP.NET-версию MVC. При этом я также решил попробовать Linq- > Sql...

Я немного смущен тем, как Linq- > Sql обрабатывает соединения.

Тривиальный пример моей схемы:

книги:
идентификатор
название

категории:
идентификатор
имя

books_categories:
book_id
category_id

Просто перетаскивание этих таблиц в файл .dbml не похоже на это. Я получаю свойство в своем классе Book_categories Book, что я ожидаю, это свойство, которое я могу перебрать и получить классы категорий напрямую.

Сейчас я должен сделать что-то очень плохое

        foreach (books_categories bc in book.books_categories)
        {
            category_names.Add(bc.Category.category.Trim());
        }

[В ответ на принятый ответ]
Я неохотно принял ответ "напишите свой собственный код клея". После продолжения моего исследования Linq- > Sql я обнаружил, что его, по-видимому, медленно отпускают в пользу (более мощной, IMO) Entity Framework. EF по-прежнему позволяет использовать LINQ для запросов и выполняет достойную работу по выяснению отношений, таких как Ruby ActiveRecord.

Ответ 1

Используйте частичную реализацию класса для книги и добавьте соответствующие методы для категорий и их свойств. Имейте свойства front-end в свойстве Books_Categories (вы можете сделать это с личной видимостью для принудительной реализации через свойство Categories).

public partial class Books
{
    public IEnumerable<string> CategoryNames
    {
       get
       {  
            return this.Books_Categories
                       .Select( bc => bc.Category.category.Trim() );
       }
    }

    public void AddCategory( Category category )
    {
       this.Books_Categories.Add( new Book_Category
                                  {
                                      Category = category,
                                      Book = this
                                  } );
    }

    public void RemoveCategory( Category category )
    {
       var bc = this.Book_Categories
                    .Where( c => c.Category == category )
                    .SingleOrDefault();
       this.Books_Categories.Remove( bc );
    }
}

Очевидно, вам нужно будет добавить проверку ошибок/ограничений и т.д., но вы получите эту идею.

Я дам вам, что это не идеально, но по крайней мере у вас есть гибкость, чтобы определить, как это работает.

Ответ 2

Многие из многих сопоставлений явно поддерживаются в Entity Framework, но не в LINQ to SQL. Вы также можете использовать сторонние ORM, такие как NHibernate.

Ответ 3

Я не думаю, что ваш ожидаемый результат поддерживается в Linq to Sql.

То, что вы делаете, может показаться неправильным, но я считаю, что один способ обойти это ограничение L2S.

Человек, мне действительно нужно попасть в Rails...

Ответ 4

Что вы можете сделать, если хотите создать книгу и прямо хотите добавить к ней категорию: на ваш взгляд:

        <p>
            <label for="CategorySelect">Category:</label>
            <%= Html.ListBox("CategorySelect") %>
            <%= Html.ValidationMessage("CategorySelect", "*")%>
        </p>  

в вашем bookcontroller:

        public ActionResult New()
    {
            var data = _entities.Categories.ToList();
        ViewData["CategorySelect"] = new MultiSelectList(data, "Id", "Name");
}

        [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult New([Bind(Exclude = "Id")] Book Booknew)
    {
        IEnumerable<int> selectedCategories = Request["CategorySelect"].Split(new Char[] { ',' }).Select(idStr => int.Parse(idStr));

        if (!ModelState.IsValid)
            return View();

        try {
            foreach(var item in selectedCategories){
                BooksCategories bc = new BooksCategories();
                bc.Book = Booknew;
                bc.CategoryId = item;
                _entities.BooksCategories.InsertOnSubmit(bc);
            }
            _entities.Books.InsertOnSubmit(Booknew);
            _entities.SubmitChanges();