#c# #entity-framework
#c# #entity-framework
Вопрос:
Я знаю, что есть много подобных проблем, но ни одна из них мне не помогла. Я получаю события из внешнего API, в котором есть вид спорта (в котором много лиг). Но когда я добавляю события, если спорт уже существует, он выдает ошибку, указанную в названии. Должен ли я фильтровать его вручную, как это делается с событиями?
public class Sport: IDbEntity
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Event> Events { get; set; }
public virtual ICollection<League> Leagues { get; set; }
}
public class Event: IDbEntity
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
public string HomeTeam { get; set; }
public string AwayTeam { get; set; }
public DateTime Date { get; set; }
public virtual League League { get; set; }
public int LeagueId { get; set; }
public virtual Sport Sport { get; set; }
public int SportId { get; set; }
public virtual ICollection<Prediction> Predictions { get; set; }
public virtual ICollection<Market> Markets { get; set; }
}
public async Task FetchEvents()
{
var root = await "https://bwin-odds.p.rapidapi.com/v1/bwin/prematch?sport_id=4"
.WithHeader("X-RapidAPI-Host", "bwin-odds.p.rapidapi.com")
.WithHeader("X-RapidAPI-Key", "..")
.GetJsonAsync<Root>();
List<Event> events = mapper.Map<List<Event>>(root.results).Take(10).ToList();
//current working solution I found
var sports = events
.Select(e => e.Sport)
.GroupBy(s => s.Id)
.Select(x => x.FirstOrDefault())
.ToList();
var leagues = events
.Select(e => e.League)
.GroupBy(l => l.Id)
.Select(x => x.FirstOrDefault())
.ToList();
await sportRepository.AddRange(sports);
await leagueRepository.AddRange(leagues);
foreach(Event e in events)
{
e.Sport = null;
e.League = null;
}
await eventRepository.AddRange(events);
}
CreateMap<Event, Result>().ReverseMap()
.BeforeMap( (src, dest) =>
{
if (src.Markets != null)
{
src.Markets = new List<BwinMarket>() { src.Markets.First() };
}
})
.AfterMap( (src, dest) =>
{
dest.SportId = src.SportId;
dest.LeagueId = src.LeagueId;
dest.League.SportId = src.SportId;
dest.Sport.Id = src.SportId;
dest.League.Id = src.LeagueId;
if (src.Markets != null)
{
dest.Markets.FirstOrDefault().EventId = int.Parse(src.Id);
}
});
public async Task AddRange(ICollection<T> entities)
{
var records = await _context.Set<T>().ToListAsync();
var entitiesToAdd = entities.Where(entity => !records.Any(record => record.Id == entity.Id));
await _context.Set<T>().AddRangeAsync(entitiesToAdd);
await _context.SaveChangesAsync();
}
Комментарии:
1. Это ошибка, потому что вы пытаетесь добавить в свою базу данных sport с тем же идентификатором, что и у существующей записи sport?
2. Я не уверен, но, похоже, у вас есть опечатка в вашем
AddRange
методе. Вместо добавления объектовawait _context.Set<T>().AddRangeAsync(entities);
, которые вы, возможно, захотите добавитьentitiesToAdd
.3. Да, это было раньше
entitiesToAdd
, просто пробовал разные варианты, не работает. Я также попытался добавить лиги и виды спорта отдельно (добавил код в edit), та же проблема.4. вы пытались добавить только sports? Я имею в виду без этих двух вызовов
await leagueRepository.AddRange(leagues); await eventRepository.AddRange(events);
. Просто чтобы узнать, работает ли это.5. Кстати, как разрешен ваш
_context
объект?