2009-01-24 14 views
10

Soy un experimentado desarrollador de Rails y pensé probar la versión ASP.NET de MVC. Al hacerlo también decidí probar Linq-> Sql ...Linq to Sql Many-Many Join Table

Estoy un poco confundido acerca de la forma en que Linq-> Sql maneja se une.

Un ejemplo trivial de mi esquema es:

libros:
id
título

categorías:
Identificación
nombre

books_categories:
book_id
category_id

simplemente arrastrando estas tablas para el archivo .dbml no parece hacerlo. Obtengo una propiedad en mi clase de libros books_categories, lo que espero es una propiedad que pueda iterar y obtener clases de Categoría directamente.

En este momento tengo que hacer algo que se siente muy mal

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

[en respuesta a la respuesta aceptada]
regañadientes acepté la respuesta de "escribir su propio código de cola". Después de continuar mi investigación de Linq-> Sql, descubrí que, al parecer, se está abandonando lentamente a favor del Marco de Entidades (más poderoso, IMO). EF todavía permite usar LINQ para consultas y hace un trabajo decente al descifrar relaciones como ActiveRecord de Ruby.

Respuesta

8

Usar una implementación de clase parcial de libro y añadir métodos apropiados para las categorías y sus propiedades. Haga que las propiedades estén en la propiedad de Books_Categories (puede hacer que esto tenga visibilidad privada para forzar la implementación a través de su propiedad de Categorías).

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); 
    } 
} 

Obviamente, tendrá que agregar algunos errores/comprobación de límites, etc. pero se entiende la idea.

Te concedo que esto no es ideal, pero al menos tienes la flexibilidad para determinar cómo funciona.

+0

wouldn' t solo puede agregar una Categoría_del_Book a this.Book_Categories en sus métodos para agregar y quitar? –

+0

Error de edición - Probablemente tecleé el código y luego renombré la propiedad. Actualizará. – tvanfosson

0

No creo que el resultado esperado sea compatible con Linq a Sql.

Lo que estás haciendo puede parecer un error, pero creo que esa es una forma de evitar esa limitación de L2S.

hombre, realmente tengo que entrar en los carriles ...

2

Muchos a muchos mapeos son explícitamente compatibles con Entity Framework, pero no en LINQ to SQL. También puede usar ORM de terceros como NHibernate.

+0

Eso me hace preguntarme por qué usaría Linq-> Sql sobre Ado.NET + Linq. Pensé que Linq-> Sql sería compatible con ORM, no hacerlo parece un paso atrás. – Bill

+1

LINQ to SQL * es * un ORM (de tipo). No utiliza LINQ to SQL con * ORM * diferente. Otros ORMs lo reemplazan. Otros ORM pueden o no admitir LINQ, pero la mayoría lo admiten. –

+0

Si Linq-Sql es un ORM, entonces esperaría que descubriera cómo hacer uniones automáticamente (de ahí la parte relacional) en lugar de tener que escribirlas yo mismo .... – Bill

0

Lo que puede hacer si desea crear un libro y directamente desea agregar una categoría a la que es: en su opinión:

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

en su bookscontroller:

 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();