我有一个具有多个导航属性的类的控制器:
public partial class Fixture
{
public int FixtureId { get; set; }
//foreign key
public int StageId { get; set; }
//navigation properties
public virtual Stage Stage { get; set; }
//foreign key
public int CityId { get; set; }
//navigation properties
public virtual City City { get; set; }
public DateTime FixtureDate { get; set; }
//foreign key
public int AwayTeamId { get; set; }
//navigation properties
public virtual Team AwayTeam { get; set; }
//foreign key
public int HomeTeamId { get; set; }
//navigation properties
public virtual Team HomeTeam { get; set; }
public byte? AwayTeamScore { get; set; }
public byte? HomeTeamScore { get; set; }
}
我现在正在编写我的第一个EntitySetController
,我希望包含3个导航属性。我知道如何包括这样的:
public IQueryable<Fixture> GetFixtures()
{
return db.Fixtures.Include("Stage");
}
是否可以包含多个导航属性?
另外,在我的帖子中如何使用这些来获取相关对象?在以前的版本ApiController
中,我编写了存储库方法来获取它们(见下文)。什么是EntitySetController
等价物?
public override HttpResponseMessage Post(Fixture fixture)
{
try
{
if (ModelState.IsValid)
{
Stage stage = _repository.GetStageByStageId(fixture.StageId);
City city = _repository.GetCityByCityId(fixture.CityId);
Team awayTeam = _repository.GetTeamByTeamName(fixture.AwayTeamName);
Team homeTeam = _repository.GetTeamByTeamName(fixture.HomeTeamName);
Fixture entity = new Fixture();
entity.StageId = stage.StageId;
entity.CityId = city.CityId;
entity.FixtureDate = fixture.FixtureDate;
entity.AwayTeamId = awayTeam.TeamId;
entity.HomeTeamId = homeTeam.TeamId;
entity.AwayTeamScore = fixture.AwayTeamScore;
entity.HomeTeamScore = fixture.HomeTeamScore;
db.Fixtures.Add(fixture);
db.SaveChanges();
var response = Request.CreateResponse(HttpStatusCode.Created, fixture);
//response.Headers.Location = new Uri(Url.Link("DefaultApi",
// new { id = fixture.FixtureId }));
return response;
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
catch
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
编辑:我使用了多个包含并引用了Post方法中的导航属性:
public override HttpResponseMessage Post(Fixture fixture)
{
try
{
if (ModelState.IsValid)
{
Fixture entity = new Fixture();
entity.StageId = fixture.Stage.StageId;
entity.CityId = fixture.City.CityId;
entity.FixtureDate = fixture.FixtureDate;
entity.AwayTeamId = fixture.AwayTeam.TeamId;
entity.HomeTeamId = fixture.HomeTeam.TeamId;
entity.AwayTeamScore = fixture.AwayTeamScore;
entity.HomeTeamScore = fixture.HomeTeamScore;
db.Fixtures.Add(entity);
db.SaveChanges();
var response = Request.CreateResponse(HttpStatusCode.Created, fixture);
return response;
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
catch
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
但是我收到400 Bad Request错误,当我查看传递的对象时,它看起来像这样
request: Object
body: "{"FixtureId":0,"StageId":0,"CityId":0,"FixtureDate":"2014-09-08T21:00:00.000","AwayTeamId":0,"HomeTeamId":0}"
callbackParameterName: "$callback"
data: Object
AwayTeam: undefined
AwayTeamId: 0
AwayTeamScore: undefined
City: undefined
CityId: 0
FixtureDate: "2014-09-08T21:00:00.000"
FixtureId: 0
HomeTeam: undefined
HomeTeamId: 0
HomeTeamScore: undefined
Stage: undefined
StageId: 0
UI看起来像这样,并且所有下拉列表都已成功填充:
<div data-ng-app="app" ng-controller="FixtureAddController">
<form name="form" class="col-xs-2" id="form" class="form-horizontal">
<div class="control-group" ng-class="{error: form.StageName.$invalid}">
<label class="control-label" for="StageName">Stage Team</label>
<div class="controls">
<select class="form-control" ng-model="fixture.StageName" ng-options="stage.StageName as stage.StageName for stage in stages" required>
<option style="display:none" value="">Select</option>
</select>
<span ng-show="form.StageName.$dirty && form.StageName.$error.required">Stage required</span>
</div>
</div>
<div class="control-group" ng-class="{error: form.CityName.$invalid}">
<label class="control-label" for="CityName">City</label>
<div class="controls">
<select class="form-control" ng-model="fixture.CityName" ng-options="city.CityName as city.CityName for city in cities" required>
<option style="display:none" value="">Select</option>
</select>
<span ng-show="form.CityName.$dirty && form.CityName.$error.required">City required</span>
</div>
</div>
<div class="control-group" ng-class="{error: form.FixtureDate.$invalid}">
<label class="control-label" for="BirthDate">Fixture Date</label>
<div class="controls">
<input type='text' class="form-control" ng-model='fixture.FixtureDate' name='FixtureDate' title="FixtureDate" ng-pattern='/^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/' required />
<span ng-show='form.FixtureDate.$dirty && form.FixtureDate.$error.required'>Fixture Date required</span>
<span ng-show='form.FixtureDate.$dirty && form.FixtureDate.$error.pattern'>Fixture Date invalid</span>
</div>
</div>
<div class="control-group" ng-class="{error: form.HomeTeamName.$invalid}">
<label class="control-label" for="HomeTeamName">Home Team</label>
<div class="controls">
<select class="form-control" ng-model="fixture.HomeTeamName" ng-options="team.TeamName as team.TeamName for team in teams" required>
<option style="display:none" value="">Select</option>
</select>
<span ng-show="form.HomeTeamName.$dirty && form.HomeTeamName.$error.required">Home Team required</span>
</div>
</div>
<div class="control-group" ng-class="{error: form.AwayTeamName.$invalid}">
<label class="control-label" for="AwayTeamName">Away Team</label>
<div class="controls">
<select class="form-control" ng-model="fixture.AwayTeamName" ng-options="team.TeamName as team.TeamName for team in teams" required>
<option style="display:none" value="">Select</option>
</select>
<span ng-show="form.AwayTeamName.$dirty && form.AwayTeamName.$error.required">Away Team required</span>
</div>
</div>
<br />
<div class="form-actions">
<button ng-show="form.$valid" ng-click="save()" class="btn btn-primary">{{action}}</button>
<a href="/Admin/Fixtures/List" class="btn btn-danger">Cancel</a>
</div>
</form>
</div>
我如何成功完成帖子?
编辑2:例如,当我将UI fixture.CityId
更改为fixture.City.CityName
以将下拉列表中的值绑定到fixture对象时,当我发布时,我收到以下错误:
Exception {name: "HTTP request failed", message: "{"$id":"1","Message":"No HTTP resource was found t…http://lovelyjubbly.cloudapp.net/odata/$batch'."}", data: Object, stack: (...), _getStackTrace: function…}
data: Object
message: "HTTP request failed"
request: Object
body: "
↵--batch_c20a-c604-4067
↵Content-Type: multipart/mixed; boundary=changeset_3cce-3259-213d
↵
↵--changeset_3cce-3259-213d
↵Content-Type: application/http
↵Content-Transfer-Encoding: binary
↵
↵POST Cities HTTP/1.1
↵Content-Id: 1
↵MaxDataServiceVersion: 3.0
↵DataServiceVersion: 3.0
↵Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1
↵Content-Type: application/json;odata=verbose
↵
↵{"CityId":0,"CityName":"Brasilia"}
↵--changeset_3cce-3259-213d
↵Content-Type: application/http
↵Content-Transfer-Encoding: binary
↵
↵POST Fixtures HTTP/1.1
↵Content-Id: 2
↵MaxDataServiceVersion: 3.0
↵DataServiceVersion: 3.0
↵Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1
↵Content-Type: application/json;odata=verbose
↵
↵{"FixtureId":0,"StageId":0,"CityId":0,"FixtureDate":"2012-11-10T22:00:00.000","AwayTeamId":0,"HomeTeamId":0,"City":{"__metadata":{"uri":"$1"}}}
↵--changeset_3cce-3259-213d--
↵
↵--batch_c20a-c604-4067--
↵"
callbackParameterName: "$callback"
data: Object
__batchRequests: Array[1]
0: Object
__changeRequests: Array[2]
0: Object
body: "{"CityId":0,"CityName":"Brasilia"}"
data: Object
headers: Object
method: "POST"
requestUri: "Cities"
__proto__: Object
1: Object
body: "{"FixtureId":0,"StageId":0,"CityId":0,"FixtureDate":"2012-11-10T22:00:00.000","AwayTeamId":0,"HomeTeamId":0,"City":{"__metadata":{"uri":"$1"}}}"
data: Object
headers: Object
method: "POST"
requestUri: "Fixtures"
__proto__: Object
length: 2
答案 0 :(得分:0)
对于您的第一个问题 - 是的,您可以包含多个导航属性。
return db.Fixtures
.Include("Stage")
.Include("FixtureDate")
.Include("AwayTeam");
等
EDIT
至于你的第二个问题 - 如果你已经将Fixtures
类定义为具有这些导航属性,并且来自db的加载会带回包含所有相关“包含”的完整图形,那么该模型应该仍然完好无损。控制器&gt;视图&gt;控制器流程。
这意味着您应该只能访问Fixture.AwayTeam.Name
之类的数据(或AwayTeam
的任何属性)。
您还可以将完整模型/图表的更改提交给EntityFramework,但是如果使用这样的断开连接的图形,您将需要有一个策略如何为图形的每个部分正确设置EntityState,否则您可能会遇到错误做的事情如下: - 提交使用现有AwayTeam的新Fixture(EF将尝试创建新的AwayTeam,而不是将现有的AwayTeam链接到新的Fixture) - 提交编辑过的Fixture和编辑过的AwayTeam
编辑2 对不起,刚刚意识到我带来了EF,你的问题不是EF。忽略EF细节!