我已经写过这几次了,但是我仍然很难看到如何使用EF4在MVC2中处理多对多关系,特别是在创建和编辑功能方面。我认为我的问题的一部分是我决定创建我的数据库表,使得数据透视表在模型本身中不可见。
我的桌子,再一次:
Games:
int GameID (primary key, auto-incr)
string GameTitle
string ReviewTitle
int Score
int ReviewContentID (foreign key from Content - News, Articles, and Game reviews all have similar content requirements)
int GenreID (foreign key from Genres)
Platforms:
int PlatformID (primary key, auto-incr)
string Name
GamePlatform (not visible in model):
int GameID (foreign key from Games)
int PlatformID (foreign key from Platforms)
当我创建一个新的评论时,我真的只想在GamePlatform数据透视表中添加条目,因为我只是想将我评论的游戏链接到现有的平台。在OOP级别处理它让我感到困惑,因为我一直在想我正在添加到平台,当我真正想要做的就是将游戏的ID链接到各种平台ID。
所以,我不想从传入的HTTP-Post数据创建一个新的平台。我只是希望能够获取表单数据并创建新游戏,新评论内容,并根据所选复选框将新游戏链接到现有平台。
我理解如何执行前两个任务。这是我似乎无法掌握的联系。
抱怨继续竖起这个,但这实际上是阻止我取得重大进展的一件事。
答案 0 :(得分:1)
假设您已在实体框架中正确映射此对象并且您的Game对象具有Platforms集合,则将现有平台分配给游戏应该就像将这些平台的ID传递给您的游戏添加/编辑操作一样简单。
在表单中,您可以使用一系列复选框,其值属性为PlatformID,并且可以使用单个公用名称“platformids”。请注意,Html.CheckBox()
HtmlHelper没有'value'参数,因此您必须通过htmlAttributes对象指定它。 MVC的默认模型绑定器将通过向接收操作添加匹配参数,自动将表单中的“platformid”值集合分组为单个类型的IEnumerable。
以下是一些可以帮助您入门的代码:
// games controller
public action AddGame(Game newGame, int[] platformIds) {
Platforms[] platforms;
if(platFormIds != null && platformIds.Any()) {
platforms = ObjectContext.Platforms.Where(ExpressionExtensions.BuildOrExpression<Platform, int>(p => p.PlatformID, platformIds)).ToList();
}
if(ModelState.IsValid()) {
game.Platforms.AddRange(platforms);
ObjectContext.AddToGames(game);
ObjectContext.SaveChanges();
}
}
// helper class
public static Expression<Func<TElement, bool>> BuildOrExpression<TElement, TValue>(Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values) {
if (valueSelector == null) throw new ArgumentNullException("valueSelector");
if (values == null) throw new ArgumentNullException("values");
ParameterExpression p = valueSelector.Parameters.Single();
if (!values.Any())
return e => false;
IEnumerable<Expression> equals = values.Select(value => (Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value, typeof(TValue))));
Expression body = equals.Aggregate(Expression.Or);
return Expression.Lambda<Func<TElement, bool>>(body, p);
}
注意:上面的BuildOrExpression()
只是创建等效于SELECT * FROM TABLE WHERE ID IN(1,2,3,4,5,...)
的SQL的好方法。