I have a Dbcontext where in its OnModelCreating()
method I have something like this:
modelBuilder.Entity<CmsContentData>().HasMany<CmsKeyword>(m =>
m.CmsKeywords).WithMany(m => m.CmsContentDatas).Map(m =>
{
m.ToTable("CmsContentData_CmsKeywords");
m.MapLeftKey("CmsContentDataID");
m.MapRightKey("CmsKeywordID");
});
I want to read from the CmsContentData_CmsKeywords
table but I wonder how ?
(there is no CmsContentData_CmsKeywords
model in the project solution)
答案 0 :(得分:1)
显然,您已经设计了一个多对多关系:每个CmsContentData
具有零个或多个CmsKeyWords
,每个CmsKeyword
被零个或多个CmsContentData
使用。 / p>
在关系数据库中,此多对多关系是使用联结表实现的。该表是您在DbContext.OnModelCreating
中提到的表。
是的,您不会将此联结表添加为DbContext中的DbSet。您的课程如下:
class CmsContentData
{
public int Id {get; set;}
// every CmsContentData has zero or more CmsKeyWords (many-to-many)
virtual ICollection<CmsKeyWord> CmsKeyWords {get; set;}
... // other properties
}
class CmsKeyWord
{
public int Id {get; set;}
// every CmsKeyWord is used by zero or more CmsContentData (many-to-many)
virtual ICollection<CmsContentData> CmsContentData{get; set;}
... // other properties
}
class MyDbContext : Dbcontext
{
public DbSet<CmsContentData> CmsContentData {get; set;}
public DbSet<CmsKeyWord> CmsKeyWords {get; set;}
}
这是Entity Framework检测到您设计了多对多关系所需要知道的一切。即使没有在OnModelCreating中的代码,它也会为您和联结表创建两个表。
仅当您对表和列的默认标识符不满意时,才需要在OnModelCreating中使用代码。
但是,如果我没有引用联结表,该如何进行联接?
答案:不要(组)加入,请使用ICollections
示例:获取带有其所有(或部分)其CmsKeyWords的CmsContentData:
var result = dbContext.CmsContextData
.Where(cmsContextData => ...) // only take certain cmsContextData
.Select(cmsContextData => new // only select properties you plan to use:
{
Id = cmsContextData.Id,
Name = cmsContextData.Name,
...
Keywords = cmsContextData.CmsKeywords
.Where(keyWord => keyWord.StartsWith(...)) // only select certain keywords
.Select(keyWord => new // only select properties you plan to use
{
Id = keyword.Id,
Text = keyWord.Text,
...
})
.ToList(),
});
实体框架足够聪明,可以检测到(组)与您的两个表联接,并且需要联接表。
反过来:
选择所有(或某些)使用某些特定CmsKeyWords的CmsContentData:
var result = dbContext.CmsKeyWords
.Where(keyWord => keyWord.StartsWith(...) // take only certain keywords
.Select(keyword => new // select only the properties you plan to use
{
Text = keyWord.Text,
...
CmsContextData = keyWord.CmsContextData // I only want specific context data
.Where(contextData => ...) // that use this Keyword
.select(contextData => new
{
... // ContextData properties you plan to use
});
});