使用LinqToSQL定义一对一关系
我正在使用现有的多语言数据库来玩LinqToSQL,但是我遇到了映射相当重要的一对一关系的问题,因此我怀疑我在数据库设计中错误地使用了该功能。
假设有两个表,Category和CategoryDetail。类别包含CategoryId(PK),ParentId和TemplateId。 CategoryDetail包含CategoryId(FK),LanguageId,Title和Description(使用适当的语言),以及CategoryId和LanguageId的组合PK。
如果将这些表拖放到LinqToSQL设计器中,则生成的对象模型将具有Category,该类别带有CategoryDetail对象的集合,这种情况永远不会发生。我希望能够在DataContext级别上过滤LanguageId,这意味着整个类别都封装在Category.CategoryDetail中,而不是所有语言版本都封装在Category.CategoryDetails中。
该数据库在我的旧对象库(旧式的自定义BOL和DAL)上运行良好,但是我担心LinqToSQL会要求对此进行更改,以便为我提供所需的结果。
使这种关系(和语言过滤)尽可能无缝的最佳方法是什么?
解决方案
我认为LINQ to SQL直接对数据库结构进行建模。
我们有两个表,因此它创建了2个对象。
我们是否看过LINQ to Entities,这使我们可以在数据库结构上方创建另一层,以使类更具可读性。
我必须假设不能为1到1的真值。听起来像在Cat Details表上有一个CatID和Lang ID的PK。那可以解释为什么要放置一个集合。我可能是错的,因为我们没有提到CatDetails表的PK
编辑:CatID和Lang ID的组合Pk使得1:m关系,而Linq to SQL实际上正在做正确的事情。唯一可能是真正的1:1的方法是,如果我们在cat表上也有一个lang ID,并且这是FK的一部分。我认为我们可能需要重新考虑我们想做什么或者如何实现它。
我们可以查看关联的属性。 (右键单击表示关联的行并显示属性。)属性将告诉我们是一对一关系还是一对多关系。通过具有单个实体关联(一对一)或者实体集关联(一对多),这在代码中得到了反映。
由于我们没有1:1的关系,因此仅映射将无法提供所需的功能。但是,很容易在自动生成的父类中提供一种可以完成此工作的方法:
public partial class Category { public IEnumerable<CategoryDetail> GetDetailsByLanguage(string langID) { return this.CategoryDetails.Where(c => c.LangID == langID); } }