首页 > 代码库 > EntityFramework 建立一对一关系

EntityFramework 建立一对一关系

前言:本来要使用实体拆分实现一对一,但发现查询时无法单独查询,影响效率,故改用手动建立一对一关系

例:

实体类:

    public class TestDbContext : DbContext
    {
        public DbSet<Test> Tests { get; set; }
        public DbSet<TestUnitPrice> TestUnitPrices { get; set; }

        public TestDbContext() : base() { }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //base.OnModelCreating(modelBuilder);

            //一对一关系中,依赖对象的主键与外键会被修改为同一个,所以在此要再次设置一下依赖对象的主键
            modelBuilder.Entity<TestUnitPrice>().HasKey(t => t.ID);
            //设置主体对象
            modelBuilder.Entity<Test>().HasRequired(t => t.UnitPrice).WithRequiredPrincipal();
        }

    }

    public class Test
    {
        public long ID { get; set; }

        public string Name { get; set; }
        public string Remarks { get; set; }
        //导航属性
        public virtual TestUnitPrice UnitPrice { get; set; }
    }

    public class TestUnitPrice
    {
        public long ID { get; set; }

        public decimal UnitPrice { get; set; }
        public string Remarks { get; set; }
    }

对应的数据库为:

技术分享

添加数据:(主体记录与依赖记录的 ID 将自动设置为相同值)

            TestDbContext db = new TestDbContext();
            //添加对象,记得同时添加依赖对象
            db.Tests.Add(new Test() {
                Name = "测试1",
                Remarks = "测试1备注",
                UnitPrice = new TestUnitPrice() {
                    UnitPrice = 10,
                    Remarks = "测试1单价备注" } });
            db.SaveChanges();

此时将生成两条SQL语句:

exec sp_executesql NINSERT [dbo].[Tests]([Name], [Remarks])
VALUES (@0, @1)
SELECT [ID]
FROM [dbo].[Tests]
WHERE @@ROWCOUNT > 0 AND [ID] = scope_identity(),N@0 nvarchar(max) ,@1 nvarchar(max) ,@0=N测试1,@1=N测试1备注
exec sp_executesql NINSERT [dbo].[TestUnitPrices]([ID], [UnitPrice], [Remarks])
VALUES (@0, @1, @2)
,N@0 bigint,@1 decimal(18,2),@2 nvarchar(max) ,@0=2,@1=10.00,@2=N测试1单价备注

同时更新主体和依赖数据:

            TestDbContext db = new TestDbContext();
            var test = db.Tests.Find(1);
            test.Remarks = "更新主实体字段01";
            test.UnitPrice.Remarks = "更新依赖实体字段01";

            db.SaveChanges();

此时将生产四条SQL语句,两条查询,两条更新

exec sp_executesql NSELECT TOP (2) 
    [Extent1].[ID] AS [ID], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[Remarks] AS [Remarks]
    FROM [dbo].[Tests] AS [Extent1]
    WHERE [Extent1].[ID] = @p0,N@p0 int,@p0=1
exec sp_executesql NSELECT 
    [Extent1].[ID] AS [ID], 
    [Extent1].[UnitPrice] AS [UnitPrice], 
    [Extent1].[Remarks] AS [Remarks]
    FROM [dbo].[TestUnitPrices] AS [Extent1]
    WHERE [Extent1].[ID] = @EntityKeyValue1,N@EntityKeyValue1 bigint,@EntityKeyValue1=1
exec sp_executesql NUPDATE [dbo].[Tests]
SET [Remarks] = @0
WHERE ([ID] = @1)
,N@0 nvarchar(max) ,@1 bigint,@0=N更新主实体字段01,@1=1
exec sp_executesql NUPDATE [dbo].[TestUnitPrices]
SET [Remarks] = @0
WHERE ([ID] = @1)
,N@0 nvarchar(max) ,@1 bigint,@0=N更新依赖实体字段01,@1=1

单独更新主体数据:

            TestDbContext db = new TestDbContext();
            var test = db.Tests.Find(1);
            test.Remarks = "更新主实体字段1";

            db.SaveChanges();

SQL:

exec sp_executesql NSELECT TOP (2) 
    [Extent1].[ID] AS [ID], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[Remarks] AS [Remarks]
    FROM [dbo].[Tests] AS [Extent1]
    WHERE [Extent1].[ID] = @p0,N@p0 int,@p0=1
exec sp_executesql NUPDATE [dbo].[Tests]
SET [Remarks] = @0
WHERE ([ID] = @1)
,N@0 nvarchar(max) ,@1 bigint,@0=N更新主实体字段1,@1=1

单独更新依赖数据:

            TestDbContext db = new TestDbContext();
            var test = db.TestUnitPrices.Find(1);
            test.Remarks = "更新依赖实体字段1";

            db.SaveChanges();

SQL:

exec sp_executesql NSELECT TOP (2) 
    [Extent1].[ID] AS [ID], 
    [Extent1].[UnitPrice] AS [UnitPrice], 
    [Extent1].[Remarks] AS [Remarks]
    FROM [dbo].[TestUnitPrices] AS [Extent1]
    WHERE [Extent1].[ID] = @p0,N@p0 int,@p0=1
exec sp_executesql NUPDATE [dbo].[TestUnitPrices]
SET [Remarks] = @0
WHERE ([ID] = @1)
,N@0 nvarchar(max) ,@1 bigint,@0=N更新依赖实体字段1,@1=1

 简单查询与删除

            TestDbContext db = new TestDbContext();
            var test = db.Tests.Include("UnitPrice").First(t => t.ID == 3);
            db.Tests.Remove(test);

            db.SaveChanges();


 

EntityFramework 建立一对一关系