Если отношения между JobType
и MMSPostage
просто один ко многим, т. Е. 1 MMSPostage
имеет 1 JobType
, а 1 JobType
имеет много MMSPostage
с, то вы можете установить как показано ниже:
Примечание:
- Мне нравится отделять модели постоянства от моделей предметной области. Таким образом, у меня есть 2 набора моделей в моем приложении (кроме моделей просмотра).
- Используется
Microsoft.EntityFrameworkCore
v2.0.3. Для v2.1.x, где функция отложенной загрузки вернулась, сущности могут выглядеть иначе, поскольку вам может понадобиться ключевое слово virtual
.
JobTypeEntity.cs
namespace DL.SO.Persistence.EFCore.Entities
{
public class JobTypeEntity
{
public int Id { get; set; }
public string Name { get; set; }
public double Cost { get; set; }
public List<MMSPostageEntity> MMSPostages { get; set; }
}
}
MMSPostageEntity.cs
namespace DL.SO.Persistence.EFCore.Entities
{
public MMSPostageEntity
{
public int Id { get; set; }
public int PieceCount { get; set; }
public double Rate { get; set; }
public int JobTypeId { get; set; }
public JobTypeEntity JobType { get; set; }
public double SubTotal
{
get
{
return (Rate + JobType.Cost) * PieceCount;
}
}
}
}
Затем вам нужно настроить свойства объекта для столбцов таблицы SQL, используя аннотации данных или свободный API. Вы можете сделать это непосредственно на OnModelCreating()
, как вы это сделали, или создать класс конфигурации для каждой сущности и применить там конфигурации.
JobTypeConfiguration.cs
namespace DL.SO.Persistence.EFCore.Configurations
{
public class JobTypeConfiguration : IEntityTypeConfiguration<JobTypeEntity>
{
public void Configure<EntityTypeBuilder<JobTypeEntity> builder)
{
builder.HasKey(x => x.Id);
builder.Property(x => x.Name).IsRequired();
builder.HasIndex(x => x.Name).IsUnique();
builder.Property(x => x.Cost).IsRequired();
builder.ToTable("JobType");
}
}
}
MMSPostageConfiguration.cs
namespace DL.SO.Persistence.EFCore.Configurations
{
public class MMSPostageConfiguration : IEntityTypeConfiguration<MMSPostageEntity>
{
public void Configure<EntityTypeBuilder<MMSPostageEntity> builder)
{
builder.HasKey(x => x.Id);
// By default, public properties with getter and setter
// will be included!
// Since the computed property SubTotal only has getter,
// it should not be included by default.
// Just in case you worry about, you can do Ignore() too!
builder.Ignore(x => x.SubTotal);
// This is how you configure the 1-to-many relationship!
builder.HasOne(x => x.JobType)
.WithMany(jt => jt.MMSPostages)
.HasForeignKey(x => x.JobTypeId);
builder.ToTable("MMSPostage");
}
}
}
AppDbContext.cs
namespace DL.SO.Persistence.EFCore
{
public class AppDbContext : DbContext
{
public class AppDbContext(DbContextOptions<AppDbContext> options)
: base(options) { }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// You apply those configurations
builder.ApplyConfiguration(new JobTypeConfiguration());
builder.ApplyConfiguration(new MMSPostageConfiguration());
}
public DbSet<JobTypeEntity> JobTypes { get; set; }
public DbSet<MMSPostageEntity> MMSPostages { get; set; }
}
}
Затем на странице редактирования вы сможете извлечь MMSPostageEntity
из базы данных, включая JobTypeEntity
, и построить для нее модель представления.
PostageController.cs
namespace DL.SO.Web.UI.Controllers
{
public class PostageController : Controller
{
private readonly AppDbContext _dbContext;
public PostageController(AppDbContext dbContext)
{
_dbContext = dbContext;
}
public IActionResult Edit(int id)
{
var postageEntity = _dbContext.MMSPostages
.AsNoTracking()
.Include(x => x.JobType)
.SingleOrDefault(x => x.Id == id);
if (postageEntity == null)
{
return NotFound();
}
// Then you can construct your view model here!
// Don't send your db entities directly to views man!
var vm = new EditPostageViewModel
{
PostageId = postageEntity.Id,
PieceCount = postageEntity.PieceCount,
Rate = postageEntity.Rate,
SubTotal = postageEntity.SubTotal,
JobType = postageEntity.JobType.Name
};
return View(vm);
}
}
}
Отказ от ответственности: Я написал все в качестве примеров вручную, поэтому они не проверены и могут даже не скомпилироваться.