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 N‘INSERT [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 N‘INSERT [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 N‘SELECT 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 N‘SELECT
    [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 N‘UPDATE [dbo].[Tests]
SET [Remarks] = @0
WHERE ([ID] = @1)
‘,N‘@0 nvarchar(max) ,@1 bigint‘,@0=N‘更新主实体字段01‘,@1=1
exec sp_executesql N‘UPDATE [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 N‘SELECT 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 N‘UPDATE [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 N‘SELECT 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 N‘UPDATE [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();
时间: 2024-10-01 04:00:56

EntityFramework 建立一对一关系的相关文章

EntityFramework之一对一关系(二)

下面新建两个实体,关系为一对一 Product为产品类,WarrantyCard为保修卡类,一个产品对应一个保修卡,一个保修卡对应一个产品. 1.新建实体类 1 public class Product 2 { 3 public int Id { get; set; } 4 public string Name { get; set; } 5 public string Description { get; set; } 6 7 public virtual WarrantyCard Warra

Hibernate_8_Person和IdCard实例_一对一关系:基于外键

1)建立Person类: public class Person { private Integer id; private String name; private IdCard IdCard; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getId() { return id; } public void setId

Entity Framework - 基于外键关联的单向一对一关系

代码的世界,原以为世界关系很简单,确道是关系无处不在.NET世界里ORM框架中EntityFramework作为其中翘楚,大大解放了搬砖工作的重复工作,着实提高了不少生产力,而也碰到过不少问题!比如关系的映射! 一对一关系的映射: 用户账户密码信息表:包含用户名 密码 邮箱等账户登录时的信息 public class SystemAccount { public SystemAccount() { Id = DateUtils.GeneratedNewGuid(); } public Guid

0914 表与表之间的关系补充一对一关系 记录操作 关键字 多对多 子查询

1 表与表之间联系之一对一关系补充 生活中的一对一 客户表, 学员表   通过分析 一个客户只对应一个学员 一个学员只对应一个客户 所以确定关系为一对一 在mysql中通过外键来建立一对一 create table customer(id int primary key auto_increment,name char(10),phone char(11),sex char(1)); create table student(id int primary key auto_increment,n

ssh免密码登陆 - 服务器建立信任关系

假设机器A,B,C,要建立A为主,可以免密码直接ssh进入B,C.操作如下: 假设只用用户yimr建立信任,则使用yimr用户登陆主机A,执行如下操作: 产生公钥和私钥 ssh-keygen -t rsa 然后,在/home/用户/.ssh目录下,产生id_rsa, id_rsa.pub文件 将公钥复制到BC节点 scp .ssh/id_rsa.pub B:/home/用户名/.ssh/A.pub 进入BC节点,将公钥放在authorized_keys文件中 cat .ssh/A.pub >>

解决Error"基础连接已经关闭: 未能为SSL/TLS 安全通道建立信任关系

今天写程序的时候调用到一个第三方的DLL文件,本机调试一切都正常,但是程序不是到服务器以后一直提示一个BUG:"基础连接已经关闭: 未能为SSL/TLS 安全通道建立信任关系". 后来把DLL文件进行反编译,发现是在获得请求的时候出错了. 引用 WebResponse response = WebRequest.Create("https://--").GetResponse(); 于是在服务器上用浏览器打开上面的地址,发现会弹出一个确认证书的窗口,看来是证书问题.

Hibernate多表关系配置——一对一关系映射

两个对象之间是一对一的关系,如Person-IdCard 有两种策略可以实现一对一的关联映射 主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系:数据库表不会有额外的字段来维护它们之间的关系,仅通过表的主键来关联 唯一外键关联 外键关联,本来是用于多对一的配置,但是如果加上唯一的限制之后,也可以用来表示一对一关联关系: 1.实体对象 1.1 Person实体对象 package demo.entity; /** * 人实体 * @author Don * @date:日期:2

MyBatis之级联——一对一关系

在学数据库概论的时候会听到这么几个词:数据库的关系分为一对一.一对多.多对多.对于在学校里学的知识已经忘得差不多了,在这里简单的提一下数据库的关系.此篇是介绍MyBatis是如何实现数据库中一对一关系的,我们就暂且先介绍一对一关系.所谓一对一关系其实在生活中很常见,比如一个学生有且只对应一个属于他的学生证.下面就是我们的所假设的数据库物理模型. 在这个数据库模型中,学生证和学生表是1对1的关系.那么基于此,我们会在Java代码的POJO包中就会有两个POJO对象,Student和SelfCard

Laravel5.1 模型 --一对一关系

这篇文章主要记录模型的一对一关系,关联关系是Model的一种非常方便的功能. 1 实现一对一关系 1.1 准备工作 首先我们需要创建两张表和对应的两个模型,第一个模型是用户表,第二个模型是账号表. 这里 我们的逻辑是:一个用户信息下只能有一个账号,一个账号只能被一个用户所拥有,这就是一对一关系. 1.1.1 用户信息表 生成模型和迁移文件: php artisan make:model UserInfo -m 编写迁移文件(表规格): public function up() { Schema: