Отношения многие ко многим через веб-API - PullRequest
0 голосов
/ 03 сентября 2018

Я пытаюсь узнать больше о Entity Framework Core. К сожалению, кажется, что вы обязываете соединительный класс, когда вы создаете отношение «многие ко многим». Пожалуйста, смотрите структуру классов ниже:

Person
Sport
PersonSport

У человека много видов спорта, а у спорта много людей. При использовании EF я бы поместил коллекцию Sport в класс Person и коллекцию Person в класс Sport. Однако теперь мне нужно создать класс PersonSport. Пожалуйста, ознакомьтесь с API-контроллером ниже (это единственный код, необходимый для устранения проблемы):

namespace WebApplication1.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class PersonController : Controller
    {
        [Route("")]
        [ProducesResponseType(typeof(Person), (int)HttpStatusCode.OK)]
        //[ProducesResponseType(typeof(IEnumerable<Sport>), (int)HttpStatusCode.OK)]
        [HttpGet]
        public async Task<IActionResult> GetPerson()
        {
            Person p1 = new Person { Id = Guid.NewGuid() };
            Sport s1 = new Sport { Id = Guid.NewGuid(), Description = "Football" };
            Sport s2 = new Sport { Id = Guid.NewGuid(), Description = "Running" };
            PersonSport ps1 = new PersonSport { Person = p1, PersonId = p1.Id, Sport = s1, SportId = s1.Id };
            PersonSport ps2 = new PersonSport { Person = p1, PersonId = p1.Id, Sport = s2, SportId = s2.Id };
            List<PersonSport> personSports = new List<PersonSport>();
            personSports.Add(ps1);
            personSports.Add(ps2);
            p1.AssignSports(personSports);
            return Ok(p1);
        }
    }

    public class Entity
    {
        public Guid Id { get; set; }
    }

    public class Person : Entity
    {
        private readonly List<PersonSport> _personSports;
        public IReadOnlyCollection<PersonSport> PersonSports => _personSports.AsReadOnly();
        //public Guid Id { get; set; }

        public Person()
        {
            _personSports = new List<PersonSport>();
        }

        public void AssignSports(IEnumerable<PersonSport> personSports)
        {
            this._personSports.AddRange(personSports);
        }
    }

    public class Sport : Entity
    {
        //public Guid Id { get; set; }
        public string Description { get; set; }
    }

    public class PersonSport
    {
        public Person Person { get; set; }
        public Sport Sport { get; set; }
        public Guid PersonId { get; set; }
        public Guid SportId { get; set; }
    }
}

Я отлаживаю проект Web API и перехожу к: http://localhost:57320/api/Person и вижу это:

enter image description here

Обратите внимание, что JSON искажен. Если я пытаюсь использовать веб-API из приложения консоли / приложения модульного тестирования; Я вижу эту ошибку:

System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
   --- End of inner exception stack trace ---
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.GetResult(Int16 token)
   at System.Net.Http.HttpConnection.FillAsync()
   at System.Net.Http.HttpConnection.ChunkedEncodingReadStream.CopyToAsyncCore(Stream destination, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.GetStringAsyncCore(Task`1 getTask)
   at ConsoleApp1.Program.CallWebAPI() 

Как я могу решить это? Код, который я использую для использования веб-API, выглядит следующим образом:

HttpClient enquiryClient = new HttpClient();
                var responseString = await enquiryClient.GetStringAsync("http://localhost:57320/api/Person");
                var response = JsonConvert.DeserializeObject<Person>(responseString);

1 Ответ

0 голосов
/ 03 сентября 2018

Я приведу вам пример, но, пожалуйста, обратите внимание, что все было бы намного проще, если бы вы добавили структуру сущностей в свой проект.

Чтобы протестировать API с вашими сущностями, это должно сработать, но учтите: боль лежит внутри ваших сущностей:

public async Task<IActionResult> GetPerson()
{
    var person = new Person() {  Id = new Guid.NewGuid() };
    var sports = new [] {
                 new Sport() { Id = Guid.NewGuid(), Description = "Football" },
                 new Sport() { Id = Guid.NewGuid(), Description = "Soccer" } };

    person.AssignSports(sports);

    return Ok(person);
}

Все остальное, с виртуальными объектами, таблицами соединений, загрузкой данных, свойствами навигации и т. Д., Придет после того, как вы внедрите платформу сущностей.

На данный момент это вернет человека с двумя видами спорта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...