Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 简化实体框架6一对一关系的语法_C#_Entity Framework_Entity Framework 6 - Fatal编程技术网

C# 简化实体框架6一对一关系的语法

C# 简化实体框架6一对一关系的语法,c#,entity-framework,entity-framework-6,C#,Entity Framework,Entity Framework 6,在断开连接的模型中使用Entity Framework 6的Web应用程序中,我有两个具有一对一关系的表: 借贷者表 借用ID(主键和FK) 商业名称 [删除其他列以保持示例简单] 借阅个人表格 借用ID(主键和FK) 全名 [删除其他列以保持示例简单] FK关系位于借用ID上。总是有借贷者记录,但偶尔也有借贷者个人记录。我已在关系上定义了级联删除 在代码中,我有以下内容(我删除了属性以保持示例的简单性): 在我的repository类中,我有以下CRUD操作: public class

在断开连接的模型中使用Entity Framework 6的Web应用程序中,我有两个具有一对一关系的表:

借贷者表

  • 借用ID(主键和FK)
  • 商业名称
  • [删除其他列以保持示例简单]
借阅个人表格

  • 借用ID(主键和FK)
  • 全名
  • [删除其他列以保持示例简单]
FK关系位于借用ID上。总是有借贷者记录,但偶尔也有借贷者个人记录。我已在关系上定义了级联删除

在代码中,我有以下内容(我删除了属性以保持示例的简单性):

在我的repository类中,我有以下CRUD操作:

public class BusinessBorrowerRepository
{
    public Borrower GetById(int id)
    {
        Borrower item;

        using (var db = new MainContext())
        {
            item = db.Borrowers
                        .Include(b => b.BorrowerIndividual)
                        .FirstOrDefault(f => f.Id == id);
        }

        return item;
    }

    public int Add(Borrower entity)
    {
        int id;

        using (var db = new MainContext())
        {
            db.Entry(entity).State = EntityState.Added;

            db.SaveChanges();

            id = (int)entity.Id;
        }

        return id;
    }

    public bool Update(Borrower entity)
    {
        using (var db = new MainContext())
        {
            if (entity.BorrowerIndividual != null)
            {
                entity.BorrowerIndividual.Id = entity.Id; // share same key, set to match

                // Test if record exists in db to determine if added or modified
                var exists = db.BorrowerIndividuals.Any(i => i.Id == entity.BorrowerIndividual.Id.Value);
                db.Entry(entity.BorrowerIndividual).State = exists ? EntityState.Modified : EntityState.Added;
            }

            db.Entry(entity).State = EntityState.Modified;

            db.SaveChanges();
        }

        return true;
    }

    public bool Delete(int id)
    {
        using (var db = new MainContext())
        {
            var entity = GetById(id);

            if (entity.BorrowerIndividual != null)
            {
                db.BorrowerIndividuals.Attach(entity.BorrowerIndividual);
                db.BorrowerIndividuals.Remove(entity.BorrowerIndividual);
                entity.BorrowerIndividual = null;
            }

            db.Borrowers.Attach(entity);
            db.Borrowers.Remove(entity);

            db.SaveChanges();
        }

        return true;
    }
}
DbContext类:

internal class MainContext : DbContext
{
   internal MainContext() : base("name=SqlServer")
   {
     Database.SetInitializer<MainContext>(null);
   }

   public virtual DbSet<Borrower> Borrowers { get; set; }
   public virtual DbSet<BorrowerIndividual> BorrowerIndividuals { get; set; }

   protected override void OnModelCreating(DbModelBuilder modelBuilder)
   {
     Database.SetInitializer<MainContext>(null); 

     modelBuilder.Configurations.Add(new BorrowerConfiguration());

     base.OnModelCreating(modelBuilder);
   }
}

class BorrowerConfiguration : EntityTypeConfiguration<Borrower>
{
  internal BusinessBorrowerConfiguration()
  {
    this.HasRequired(x => x.BorrowerIndividual).WithRequiredPrincipal();   
  }
}
内部类MainContext:DbContext
{
内部MainContext():base(“name=SqlServer”)
{
Database.SetInitializer(null);
}
公共虚拟数据库集{get;set;}
公共虚拟数据库集借用者个人{get;set;}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
Database.SetInitializer(null);
modelBuilder.Configurations.Add(新的借用配置());
基于模型创建(modelBuilder);
}
}
类借用配置:EntityTypeConfiguration
{
内部BusinessBorrowerConfiguration()
{
this.HasRequired(x=>x.BorrowerIndividual).WithRequiredPrincipal();
}
}
GetById和Add看起来非常典型。更新和删除似乎过于冗长。我能做些什么来允许:

  • 更新只需设置“db.Entry(entity.State= EntityState.Modified“无需设置 你是个人吗
  • 有没有一种方法可以执行更简单的任务 删除将级联而不显式删除的 你是个人吗

  • 总的来说,似乎要让它发挥作用需要做更多的工作

    两种方法都可以简化。但首先确保级联删除已启用(因为默认情况下它不是):

    但请注意,如果没有具有指定的
    Id
    的记录,它将异常失败。因此,更安全的版本是这样的(不要使用使用不同上下文的
    GetById
    方法,也不要
    包含相关数据,因为我们将依赖数据库级联删除):

    更新:

    这适用于
    借用个人
    修改的所有场景(
    null
    new
    -插入
    现有
    null
    删除
    现有
    现有
    更新
    )。唯一的缺点是,在最后一种情况下,即使没有更改任何属性,它也总是为
    借款者个人
    生成
    更新
    命令。因此,如果您想以多出几行代码的代价优化数据库命令,可以使用以下方法:

    var existing = db.Borrowers.Include(e => e.BorrowerIndividual).FirstOrDefault(e => e.Id == entity.Id);
    db.Entry(existing).CurrentValues.SetValues(entity);
    if (existing == null) return; // ??
    if (existing.BorrowerIndividual != null && entity.BorrowerIndividual != null)
    {
        entity.BorrowerIndividual.Id = existing.Id;
        db.Entry(existing.BorrowerIndividual).CurrentValues.SetValues(entity.BorrowerIndividual);
    }
    else
        existing.BorrowerIndividual = entity.BorrowerIndividual;
    db.SaveChanges();
    

    在EF中处理断开连接的实体从来都不容易。

    使用级联删除,通过不使用
    GetById
    ,而是使用
    db
    变量或仅使用存根实体,可以简化
    delete
    方法。对于
    Update
    ,您没有其他选择,因为您正在接收分离的对象。我尝试不使用GetById,而只是附加到仅具有Id的对象的新实例。问题是,由于需要先删除相关的借阅行,我在保存时遇到FK错误。我还必须添加entity.BorrowerIndividual=null行,否则它可能会抱怨SaveChanges。似乎比应该做的还要多。我有一个将此对象作为属性的父对象,以及其他子对象,因此更新和删除非常长。创建存储过程可能更有意义,它将尊重SQL中的级联删除
    var entity=db.借款人.FirstOrDefault(e=>e.Id==Id);db.借款人。移除(实体)为我工作。但是请注意,由于发布的安装程序没有激活cascade delete,我必须在调用
    WithRequiredPrincipal()
    之后添加
    。Willcascade ondelete()
    。@IvanStoev,这确实清除了删除!由于我没有收到任何关于更新的其他反馈,如果您将此作为答案发布,我可以接受,因为它清除了我的删除。您对ASP.NET MVC to SQL的更好的ORM有什么建议吗?在过去4年中,我在大约6个应用程序上使用了EF,在此之前,我使用了MS Enterprise Library数据访问应用程序块和存储过程。EL并不是一个真正的ORM,但我确实节省了大量重复的ADO.NET调用。尽管仍有大量无意识的重复工作在构建CRUD存储过程,并映射所有属性。不。唯一的竞争对手是NHibernate,但IMO EF更直观。查询部分很好,CRUD将很容易跟踪上下文的服务。唯一困难的是使用断开连接的实体/DTO的CRUD,但通过一些重复代码,一切都可以解决。有一个开源软件包正在解决最后一个问题,但不幸的是,它不再受支持。我尝试了第二个更新建议,但它引发了以下异常:EntityFramework.dll中发生了类型为“System.InvalidOperationException”的异常,但未在用户代码中处理。其他信息:属性“Id”是对象密钥信息的一部分,无法删除被改进的。在以下行:db.Entry(现有).CurrentValues.SetValues(实体);我弄明白了,需要过滤记录:var existing=db.fourses.Include(e=>e.fourneridividual).FirstOrDefault(e=>e.Id==entity.Id);我更新了你的答案以反映这一变化。绝对-这正是我在发帖前的想法和测试,但忘了把它放进去
    modelBuilder.Entity<Borrower>()
        .HasRequired(x => x.BorrowerIndividual)
        .WithRequiredPrincipal()
        .WillCascadeOnDelete();
    
    db.Entry(new Borrower { Id = id }).State = EntityState.Deleted;
    db.SaveChanges();
    
    var existing = db.Borrowers.FirstOrDefault(e => e.Id == id);
    if (existing == null) return; // ??
    db.Borrowers.Remove(existing);
    db.SaveChanges();
    
    var existing = db.Borrowers.Include(e => e.BorrowerIndividual).FirstOrDefault(e => e.Id == entity.Id);
    if (existing == null) return; // ??
    db.Entry(existing).CurrentValues.SetValues(entity);
    existing.BorrowerIndividual = entity.BorrowerIndividual;
    db.SaveChanges();
    
    var existing = db.Borrowers.Include(e => e.BorrowerIndividual).FirstOrDefault(e => e.Id == entity.Id);
    db.Entry(existing).CurrentValues.SetValues(entity);
    if (existing == null) return; // ??
    if (existing.BorrowerIndividual != null && entity.BorrowerIndividual != null)
    {
        entity.BorrowerIndividual.Id = existing.Id;
        db.Entry(existing.BorrowerIndividual).CurrentValues.SetValues(entity.BorrowerIndividual);
    }
    else
        existing.BorrowerIndividual = entity.BorrowerIndividual;
    db.SaveChanges();