I'm using EF Core and have the following project structure
AppName.Entity
- Alert
- Other classes
AppName.Repository
- AlertRepository
- Other Repository classes
The alert entity is as follows:
using System;
using System.ComponentModel.DataAnnotations;
namespace AppName.Entity
{
public class Alert
{
[Key]
public int AlertId { get; set; }
public string RuleId { get; set; }
public string DeviceId { get; set; }
public string VehicleVin { get; set; }
public string AlertText { get; set; }
public DateTime DateTimeUtc { get; set; }
public AlertCategory AlertCategory { get; set; }
}
public enum AlertCategory
{
VehicleHealth = 1,
FleetHealth = 2,
EmissionsHealth = 3,
Fuel = 4,
AssetUtilization = 5,
Safety = 6,
DutyCycle = 7
}
}
AlertRepository.cs
is as follows:
using AppName.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace AppName.Repository
{
public class AlertRepository// : GenericRepository<Alert>, IAlertRepository
{
public async Task<int> Save(Alert alert)
{
using (AFIdbContext context = new AFIdbContext())
{
context.Alerts.Add(alert);
await context.SaveChangesAsync();
return alert.AlertId;
}
}
public async Task<bool> Save(IEnumerable<Alert> alerts)
{
using (AFIdbContext context = new AFIdbContext())
{
foreach (Alert alert in alerts)
{
context.Alerts.Add(alert);
}
await context.SaveChangesAsync();
return true;
}
}
public IQueryable<Alert> GetList(DateTime fromDate, DateTime toDate, int pageSize, int pageNum)
{
using (AFIdbContext context = new AFIdbContext())
return context.Alerts.Where(x => x.DateTimeUtc >= fromDate && x.DateTimeUtc <= toDate).Skip(pageSize * pageNum).Take(pageSize);
}
}
}
AFIdbContext.cs
using AppName.Entity;
using Microsoft.EntityFrameworkCore;
using System.Configuration;
namespace AppName.Repository
{
public class AFIdbContext : DbContext
{
private string _afiConnstring;
public string AFIConnstring
{
get
{
if (_afiConnstring != null)
return _afiConnstring;
else
return "";
}
}
public AFIdbContext() : base()
{
}
public AFIdbContext(DbContextOptions<AFIdbContext> options) : base(options)
{
}
public DbSet<Alert> Alerts { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<UserAlertPreference> UserAlertPreferences { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<AlertRepository>().ToTable("Alert");
modelBuilder.Entity<User>().ToTable("User");
modelBuilder.Entity<UserAlertPreference>().ToTable("UserAlertPreference");
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlServer(AppExtensions.ConnString);
}
}
}
When I attempt to save a collection of Alerts, I get the following exception:
System.InvalidOperationException: 'The entity type 'AlertRepository' requires a primary key to be defined. If you intended to use a keyless entity type call 'HasNoKey()'.'
The Alert
entity does have a primary key in the DB and does have the [Key]
attribute. Why is it telling me that the AlertRepository
object doesn't have the key set when it's an Alert
Entity I am trying to save? Can I not have the Entity in a separate project? I'm trying to follow a DDD pattern
The exception is being thrown before it even tries to save the records
(I have a breakpoint on await context.SaveChangesAsync();
in AlertRepository
The solution here doesn't help because I already have those set
CodePudding user response:
You have mapped the wrong entity in your OnModelCreating
for table Alert.
Try with
modelBuilder.Entity<Alert>().ToTable("Alert")
CodePudding user response:
AlertRepository is not right class to be an entity, you just have to map the Alert entity in OnModelCreating
Replace
modelBuilder.Entity().ToTable("Alert");
with
modelBuilder.Entity().ToTable("Alert")
or you can just remove this line because entity framework will create a table for you with same name as your entity.