技术开发 频道

步步学LINQ to SQL:为实体类添加关系

  虽然你可以在Author中实现相同的功能(因为每个作者都可以有多本书),但是使用authorId取代bookId:

  [Table( Name = "Authors" )]

  
public class Author

  {

  ...

  
private EntitySet _bookAuthors = new EntitySet( );

  [Association( Name
= "FK_BookAuthors_Authors",

  Storage
= "_bookAuthors",

  OtherKey
= "authorId", ThisKey = "Id" )]

  
private ICollection BookAuthors {

  
get { return _bookAuthors; }

  
set { _bookAuthors.Assign( value ); }

  }

  2. 添加一个公有属性,通过1:M的关系使用LINQ 来检索枚举数据。

  最后,通过创建Authors属性从该书实例的私有书作者列表中检索所有作者。例如,如果你有一本LINQ In Action的书,该书就有三个作者:Fabrice Marguerie, Steve Eichert, 和Jim Wooley,那么LINQ In Action Book实例将包涵三个BookAuthors的列表:

  你想要做的就是检索作者列表,因此调用者甚至不必了解有这样一个中间表的存在。你可以通过使用LINQ来查询该私有BookAuthors属性并仅仅返回所查找的作者:

  IEnumerable authors = from ba in BookAuthors

  select ba.Author;

   现在,你可以在Book中将其包装成一个名位为Authors的公有、只读属性,并且(可选)通过在结果集中调用toList()返回一个ICollection集合,正如我在这里所实现的那样,为其提供一些更多的公共接口:

  public ICollection Authors { get {

  
return ( from ba in BookAuthors select ba.Author ).ToList( ); } }

   当然,在Author中你可以实现相同的功能来返回一个作者的所有书籍:

  public ICollection Books { get {

  
return ( from ba in BookAuthors select ba.Book ).ToList( ); } }

   从M:M的关系中访问数据

  现在,你可以完全地如愿操作你的对象模型。下面是一些例子:

  // Starting from Books...

  
foreach( var book in bookCatalog.Books ) {

  
string title = book.Title;

  
decimal price = book.Price;

  
string category = book.Category.Name;

  ICollection authors
= book.Authors;

  ICollection otherBooksInCategory
= book.Category.Books;

  }

  
// Starting from Authors...

  
foreach( var author in bookCatalog.Authors ) {

  
string name = author.Name;

  ICollection books
= author.Books;

  }

  
// Starting from Categories...

  
foreach( var category in bookCatalog.Categories ){

  
string name = category.Name;

  
foreach( var book in category.Books ){

  
string bookTitle = book.Title;

  ICollection bookAuthors
= book.Authors;

  }

  }

   从未使用/分配警告

  有件事情你可能需要注意的是你为LINQ创建的中间变量(虽然仅仅获得了对Association特性的引用,但是其它部分从来未使用过)将会引起Visual Studio提示为警告,消息为这些值从未使用和分配。当然,它们实际上都被使用被进行了值的分配,但是后台编译器却不能探测到。你可以抑制这些警告的发生,正如我在附件代码中阐述的那样,使用pragma 预处指令取代上面需要映射到数据库的每个类或字段:

  // disable never used/assigned warnings for fields that are being used by LINQ

  
#pragma warning disable 0169, 0649
0
相关文章