但是,我无法让它正常工作,而且我确信我的做法非常简单.这是我尝试过的图表:
联结表的要点是我需要在关系中有一个额外的属性Level,所以我不能只顾问顾问和程序之间的直接关系.我在设计器中手动添加了ConsultantProgramLink实体,然后分别向Program和Consultant添加了关联,选择为每个添加FK,然后将它们作为主键.但是,当我这样做时,它不能像我预期的那样工作:
如果我在顾问和程序之间建立了直接关联,那么我可以在我的代码中引用Consultant.Programs.但现在使用联结表不起作用.有没有办法解决这个问题,或者我是否总是需要通过交汇点属性(Consultant.ConsultantProgramLink.Programs)?在任何情况下,即使我尝试通过交汇处属性也无济于事.我可以在我的代码中做Consultant.ConsultantProgramLink,但是另一个点没有给我导航属性程序(由于某种原因它也变成了简单的程序,为什么?如果我最终可以访问它们,我可以重命名它们吗?) .
解决方法
public IEnumerable<Program> Programs { get { return this.ConsultantProgramLinks.Select(l => l.Program); } }
这个例子也解释了你的上一个问题.您不能在ConsultantProgramLink上拥有Program属性,因为它是相关实体的集合,而不是单个实体(应该称为ConsultantProgramLinks). ConsultantProgramLink实体中的属性简单地称为Programbe,因为它表示单个实体而不是集合.
编辑:
如果您需要自动将每个程序与每个顾问相关联,则必须在创建新程序时强制执行该程序.将联结表暴露为单独的实体可能会让您轻松实现:
var program = new Program(); ... context.Programs.AddObject(program); var ids = from c in context.Consultants select c.Id; foreach (var id in ids) { var link = new ConsultantProgramLink { ConsultantId = id,Program = program }; context.ConsultantProgramLinks.AddObject(link); } context.SaveChanges();
缺点是,如果你有1000个顾问,这个构造将创建1001个数据库插入,其中每个插入将在单独的往返数据库中执行.要避免它,唯一的选择是在Program表上使用存储过程或触发器.