如何添加/更新/删除子实体

时间:2016-01-08 19:28:21

标签: c# asp.net asp.net-mvc entity-framework

在Asp.net mvc实体框架上工作,面对子实体添加/更新/删除部分的问题。

enter image description here 这是我的关系

public class Client
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ClientId { get; set; }
    public string ClientName { get; set; }
    public string CompanyAddress1 { get; set; }
    public string CompanyAddress2 { get; set; }
    public string Phone { get; set; }
    public string Email { get; set; }
    public string ContactPerson { get; set; }
    public string ContactPersonPhone { get; set; }
    public virtual ICollection<Job> Jobs { get; set; }
}

public class Job
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int JobId { get; set; }
    public string JobDescription { get; set; }
    public decimal EstamationCost { get; set; }

    public DateTime EstemateDelevaryTime { get; set; }
    public virtual Client Client { get; set; }

}

public class Context : DbContext
{
    public DbSet<Job > Jobs { get; set; }
    public DbSet<Client> Clients { get; set; }
}

请查看我的工作实体,它不包含任何父ID,只包含关系。

想知道如何在子实体上创建任何条目/更新/删除。我使用了以下语法来创建:

    [HttpPost]
    public async Task<ActionResult> Create(JobManageViewModel model)
    {
        if (ModelState.IsValid)
        {
            _unitOfWorkAsync.BeginTransaction();
            try
            {
                var application = model.ToDalEntity();
                application.ObjectState = ObjectState.Added;
                _jobService.Insert(application);
                var changes = await _unitOfWorkAsync.SaveChangesAsync();
                _unitOfWorkAsync.Commit();
                return RedirectToAction("Index");
            }
            catch
            {
                // Rollback transaction
                _unitOfWorkAsync.Rollback();
            }
        }
        LoadClientsInViewData();
        return View(model);
    }


public Job ToDalEntity(Job model)
{
    model.JobId = this.JobId;
    model.JobDescription = this.JobDescription;
    model.EstamationCost = this.EstamationCost;
    model.EstemateDelevaryTime = this.EstemateDelevaryTime;

    return model;
}

问题是无法在Job表上插入客户端信息。如何在作业表上插入/更新/删除客户端信息

1 个答案:

答案 0 :(得分:1)

这是一种可行的方法,但我强烈建议您不要这样做,因为这实际上是一种不好的做法,您将打破SOLID原则,等等。

但你可以这样做:

配置关系表

我创建了两个独立的类,每个表一个

客户端配置

public class ClientEntityTypeConfiguration : EntityTypeConfiguration<Client>
{
    public ClientEntityTypeConfiguration()
    {
        HasKey(x => x.ClientId);
        Property(x => x.ClientId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        HasMany(x => x.Jobs).WithOptional(x => x.Client);
    }
}

作业配置

public class JobEntityTypeConfiguration : EntityTypeConfiguration<Job>
{
    public JobEntityTypeConfiguration()
    {
        HasKey(x => x.JobId);
        Property(x => x.JobId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        HasOptional(x => x.Client).WithMany(x => x.Jobs);
    }
}

在您的上下文类中,您将这些类设置为您的配置:

public class MyContext : DbContext
{
    public DbSet<Client> Clients { get; set; }
    public DbSet<Job> Jobs { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Configurations.Add(new ClientEntityTypeConfiguration());
        modelBuilder.Configurations.Add(new JobEntityTypeConfiguration());
        base.OnModelCreating(modelBuilder);
    }
}

将已创建的客户端添加到Job实体的技巧是,您必须设置Client的新实例,并仅设置Id,然后告诉您的Context,该实例已存在于数据库中。

var clientAlreadyExists = new Client {ClientId = 1};
context.Clients.Attach(clientAlreadyExists);
job.Client = clientAlreadyExists;        

context.Jobs.Add(product);

我建议你使用Repository Pattern,不要直接从你的Controller访问你的上下文,再一次对你这么说,你的方法是一个糟糕的做法