diff --git a/samples/AspNetCore3xEndpointSample.Web/AspNetCore3xEndpointSample.Web.csproj b/samples/AspNetCore3xEndpointSample.Web/AspNetCore3xEndpointSample.Web.csproj
index 49f3a29ef6..37258518c0 100644
--- a/samples/AspNetCore3xEndpointSample.Web/AspNetCore3xEndpointSample.Web.csproj
+++ b/samples/AspNetCore3xEndpointSample.Web/AspNetCore3xEndpointSample.Web.csproj
@@ -5,9 +5,10 @@
-
+
+
diff --git a/samples/AspNetCore3xEndpointSample.Web/Controllers/CustomersController.cs b/samples/AspNetCore3xEndpointSample.Web/Controllers/CustomersController.cs
index d447550659..9008d10d9c 100644
--- a/samples/AspNetCore3xEndpointSample.Web/Controllers/CustomersController.cs
+++ b/samples/AspNetCore3xEndpointSample.Web/Controllers/CustomersController.cs
@@ -6,10 +6,10 @@
using AspNetCore3xEndpointSample.Web.Models;
using Microsoft.AspNet.OData;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.EntityFrameworkCore;
+
namespace AspNetCore3xEndpointSample.Web.Controllers
-{
+{/*
public class CustomersController : ODataController
{
private readonly CustomerOrderContext _context;
@@ -87,4 +87,85 @@ public IActionResult Get(int key)
return Ok(_context.Customers.FirstOrDefault(c => c.Id == key));
}
}
+ */
+ public class CustomersController : ODataController
+ {
+ private readonly IList _customers;
+
+ public CustomersController(/*CustomerOrderContext context*/)
+ {
+ _customers = new List
+ {
+ new Customer
+ {
+ ID = 123,
+ CustomerReferrals = new List
+ {
+ new CustomerReferral { ID = 8, CustomerID = 123, ReferredCustomerID = 8},
+ new CustomerReferral { ID = 9, CustomerID = 123, ReferredCustomerID = 9},
+ },
+ Phones = Enumerable.Range(0, 2).Select(e =>
+ new CustomerPhone { ID = 11, CustomerID = 123, Formatted = new CustomerPhoneNumberFormatted { CustomerPhoneNumberID = 17, FormattedNumber = "171" } }
+ ).ToList()
+ },
+ new Customer
+ {
+ ID = 456,
+ CustomerReferrals = new List
+ {
+ new CustomerReferral { ID = 18, CustomerID = 456, ReferredCustomerID = 8},
+ new CustomerReferral { ID = 19, CustomerID = 456, ReferredCustomerID = 9},
+ },
+ Phones = Enumerable.Range(0, 2).Select(e =>
+ new CustomerPhone { ID = 21 + e, CustomerID = 456 + e, Formatted = new CustomerPhoneNumberFormatted { CustomerPhoneNumberID = 17 + e, FormattedNumber = "abc" } }
+ ).ToList()
+ },
+ //new Customer
+ //{
+ // Name = "Peter",
+ // HomeAddress = new Address { City = "Hollewye", Street = "Main St NE"},
+ // FavoriteAddresses = new List
+ // {
+ // new Address { City = "R4mond", Street = "546 NE"},
+ // new Address { City = "R4d", Street = "546 AVE"},
+ // },
+ // Order = new Order { Title = "Jichan" },
+ // Orders = Enumerable.Range(0, 2).Select(e => new Order { Title = "ijk" + e }).ToList()
+ //},
+ };
+
+ foreach (var customer in _customers)
+ {
+ foreach (var refed in customer.CustomerReferrals)
+ {
+ refed.ReferredCustomer = customer;
+ refed.Customer = customer;
+ }
+ }
+
+ }
+
+ [EnableQuery]
+ public IActionResult Get()
+ {
+ // Be noted: without the NoTracking setting, the query for $select=HomeAddress with throw exception:
+ // A tracking query projects owned entity without corresponding owner in result. Owned entities cannot be tracked without their owner...
+ // _context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
+
+ return Ok(_customers);
+ }
+
+ [EnableQuery]
+ public IActionResult Get(int key)
+ {
+ return Ok(_customers.FirstOrDefault(c => c.ID == key));
+ }
+
+ [EnableQuery(MaxExpansionDepth = 5)]
+ public IActionResult GetCustomerReferrals(int key)
+ {
+ var c = _customers.FirstOrDefault(c => c.ID == key);
+ return Ok(c.CustomerReferrals);
+ }
+ }
}
diff --git a/samples/AspNetCore3xEndpointSample.Web/Models/CustomerOrder.cs b/samples/AspNetCore3xEndpointSample.Web/Models/CustomerOrder.cs
index 5ac809cf4f..508b7a74d4 100644
--- a/samples/AspNetCore3xEndpointSample.Web/Models/CustomerOrder.cs
+++ b/samples/AspNetCore3xEndpointSample.Web/Models/CustomerOrder.cs
@@ -3,10 +3,9 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
-using Microsoft.EntityFrameworkCore;
namespace AspNetCore3xEndpointSample.Web.Models
-{
+{/*
public class Customer
{
public int Id { get; set; }
@@ -35,5 +34,5 @@ public class Address
public string City { get; set; }
public string Street { get; set; }
- }
+ }*/
}
diff --git a/samples/AspNetCore3xEndpointSample.Web/Models/CustomerOrderContext.cs b/samples/AspNetCore3xEndpointSample.Web/Models/CustomerOrderContext.cs
index 6c6e4fff2e..8ec4a310b8 100644
--- a/samples/AspNetCore3xEndpointSample.Web/Models/CustomerOrderContext.cs
+++ b/samples/AspNetCore3xEndpointSample.Web/Models/CustomerOrderContext.cs
@@ -1,24 +1,35 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
-using Microsoft.EntityFrameworkCore;
+//using Microsoft.EntityFrameworkCore;
+
+using System.Data.Entity;
namespace AspNetCore3xEndpointSample.Web.Models
{
public class CustomerOrderContext : DbContext
{
- public CustomerOrderContext(DbContextOptions options)
- : base(options)
+ //public CustomerOrderContext(DbContextOptions options)
+ // : base(options)
+ //{
+ //}
+
+ public CustomerOrderContext(string connectString)
+ : base(connectString)
{
}
public DbSet Customers { get; set; }
- public DbSet Orders { get; set; }
+ // public DbSet Orders { get; set; }
- protected override void OnModelCreating(ModelBuilder modelBuilder)
+ protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
- modelBuilder.Entity().OwnsOne(c => c.HomeAddress).WithOwner();
+ modelBuilder.Entity().HasOptional(a => a.Formatted).WithRequired();
+ modelBuilder.Entity()
+ .HasMany(c => c.CustomerReferrals)
+ .WithRequired(c => c.Customer)
+ .HasForeignKey(c => c.CustomerID);
}
}
}
diff --git a/samples/AspNetCore3xEndpointSample.Web/Models/EdmModelBuilder.cs b/samples/AspNetCore3xEndpointSample.Web/Models/EdmModelBuilder.cs
index 53f68d0e13..5cb6a5d351 100644
--- a/samples/AspNetCore3xEndpointSample.Web/Models/EdmModelBuilder.cs
+++ b/samples/AspNetCore3xEndpointSample.Web/Models/EdmModelBuilder.cs
@@ -3,6 +3,9 @@
using Microsoft.AspNet.OData.Builder;
using Microsoft.OData.Edm;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
namespace AspNetCore3xEndpointSample.Web.Models
{
@@ -15,8 +18,9 @@ public static IEdmModel GetEdmModel()
if (_edmModel == null)
{
var builder = new ODataConventionModelBuilder();
- builder.EntitySet("Customers");
- builder.EntitySet("Orders");
+ var customers = builder.EntitySet("Customers");
+ customers.Binding.HasManyPath(c => c.CustomerReferrals, true).HasRequiredBinding(r => r.ReferredCustomer, "Customers");
+ // builder.EntitySet("Orders");
_edmModel = builder.GetEdmModel();
}
@@ -24,4 +28,54 @@ public static IEdmModel GetEdmModel()
}
}
+
+ public class Customer
+ {
+ [Key]
+ public int ID { get; set; }
+
+ [Contained]
+ public virtual ICollection CustomerReferrals { get; set; }
+
+ [Contained]
+ public virtual ICollection Phones { get; set; }
+ }
+
+ public class CustomerReferral
+ {
+ [Key]
+ public int ID { get; set; }
+
+ public int CustomerID { get; set; }
+
+ public int ReferredCustomerID { get; set; }
+
+ [Required]
+ [ForeignKey(nameof(CustomerID))]
+ public virtual Customer Customer { get; set; }
+
+ [Required]
+ [ForeignKey(nameof(ReferredCustomerID))]
+ public virtual Customer ReferredCustomer { get; set; }
+ }
+
+ public class CustomerPhone
+ {
+ [Key]
+ public int ID { get; set; }
+
+ [Editable(false)]
+ public int CustomerID { get; set; }
+
+ [Contained]
+ public virtual CustomerPhoneNumberFormatted Formatted { get; set; }
+ }
+
+ public class CustomerPhoneNumberFormatted
+ {
+ [Key]
+ public int CustomerPhoneNumberID { get; set; }
+
+ public string FormattedNumber { get; set; }
+ }
}
\ No newline at end of file
diff --git a/samples/AspNetCore3xEndpointSample.Web/Startup.cs b/samples/AspNetCore3xEndpointSample.Web/Startup.cs
index 667d735e05..cd34fce8cd 100644
--- a/samples/AspNetCore3xEndpointSample.Web/Startup.cs
+++ b/samples/AspNetCore3xEndpointSample.Web/Startup.cs
@@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
-using System;
-using System.Collections.Generic;
using AspNetCore3xEndpointSample.Web.Models;
using Microsoft.AspNet.OData.Batch;
using Microsoft.AspNet.OData.Extensions;
@@ -11,12 +9,13 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
-using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OData;
using Microsoft.OData.Edm;
+using System;
+using System.Collections.Generic;
namespace AspNetCore3xEndpointSample.Web
{
@@ -32,7 +31,8 @@ public Startup(IConfiguration configuration)
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
- services.AddDbContext(opt => opt.UseLazyLoadingProxies().UseInMemoryDatabase("CustomerOrderList"));
+ //services.AddDbContext(opt => opt.UseLazyLoadingProxies().UseInMemoryDatabase("CustomerOrderList"));
+ //services.AddScoped(_ => new CustomerOrderContext(Configuration.GetConnectionString("DefaultConnection")));
services.AddOData();
services.AddRouting();
}
@@ -54,6 +54,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
app.UseEndpoints(endpoints =>
{
+ endpoints.Expand();
endpoints.MapODataRoute(
"nullPrefix", null,
b =>
diff --git a/samples/AspNetCore3xEndpointSample.Web/appsettings.json b/samples/AspNetCore3xEndpointSample.Web/appsettings.json
index d9d9a9bff6..a992a10255 100644
--- a/samples/AspNetCore3xEndpointSample.Web/appsettings.json
+++ b/samples/AspNetCore3xEndpointSample.Web/appsettings.json
@@ -1,4 +1,7 @@
{
+ "ConnectionStrings": {
+ "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=EF6MVCCore;Trusted_Connection=True;MultipleActiveResultSets=true"
+ },
"Logging": {
"LogLevel": {
"Default": "Information",
diff --git a/src/Microsoft.AspNet.OData.Shared/Query/ODataQueryOptions.cs b/src/Microsoft.AspNet.OData.Shared/Query/ODataQueryOptions.cs
index 13da5b7cfb..67a16cebb3 100644
--- a/src/Microsoft.AspNet.OData.Shared/Query/ODataQueryOptions.cs
+++ b/src/Microsoft.AspNet.OData.Shared/Query/ODataQueryOptions.cs
@@ -73,8 +73,7 @@ private void Initialize(ODataQueryContext context)
_queryOptionParser = new ODataQueryOptionParser(
context.Model,
- context.ElementType,
- context.NavigationSource,
+ context.Path.Path,
normalizedQueryParameters);
// Note: the context.RequestContainer must be set by the ODataQueryOptions constructor.