2014-01-20 32 views
1

我有一個具有多個導航屬性的類控制器:EntitySetController多個導航性能

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); 
    } 
} 

編輯:我已經使用了多種包括和引用的中郵方法導航性能:

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錯誤請求的錯誤,當我考慮對象通過它看起來這樣

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.CityIdfixture.City.CityName的值在下拉綁定到固定的對象,當我發表我得到以下錯誤:

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

第一個問題 - 是的,您可以包含多個導航屬性。

return db.Fixtures 
    .Include("Stage") 
    .Include("FixtureDate") 
    .Include("AwayTeam"); 

編輯 關於你的第二個問題 - 如果已經定義了你Fixtures類具有的導航性能,並從數據庫負載帶回總圖與所有相關「包括',那麼在Controller> View> Controller流程之後,該模型應該仍然完好無損。 這意味着您應該能夠訪問像Fixture.AwayTeam.Name(或任何AwayTeam的屬性可能看起來像)的數據。

您也可以將完整模型/圖形的更改提交給EntityFramework,但是像這樣的一個不連續的圖表,您需要有一個策略,以便如何正確設置圖表的每個部分的EntityState,否則可能會出錯做事情時,如: - 提交採用現有AwayTeam新的燈具(EF將嘗試創建一個新的AwayTeam,而不是現有的AwayTeam鏈接到新燈) - 提交編輯夾具和編輯AwayTeam

編輯2 對不起,剛纔意識到我帶來了EF,你的問題不是EF。忽略EF的細節!

+0

關於第二個問題,如果我想創建一個FixtureDTO,其中包括例如實際的StageName而不是外鍵的StageId,我可以在Post方法中使用Get/Fixture(5)/ Stage(如果是的話)會是語法),還是我會使用上面使用的類型的方法?另外,使用多個包含所有外鍵數據是否是一個好主意,這不會減慢執行速度嗎? – user517406

+0

RE:使用多個包含的好主意。這真的取決於你的需求。是的,它會增加您的數據傳輸,因爲您現在引入的不僅僅是基礎實體。但是,如果你需要包含在包含內的信息,那麼你需要把它帶回來。 – Mashton

+0

請參閱上面的編輯 – user517406