使用 LINQ (C#) 时 SQL Server 中的 TinyInt 数据类型不保存 0 整数

Posted

技术标签:

【中文标题】使用 LINQ (C#) 时 SQL Server 中的 TinyInt 数据类型不保存 0 整数【英文标题】:TinyInt datatype in SQL Server does not save 0 integer when using LINQ (C#) 【发布时间】:2021-11-18 04:30:26 【问题描述】:

我有一个像这样的简单实体:

public partial class TestEntity
   public int Id  get; set;  // primary key
    public string Relation  get; set; 
    public byte? Age  get; set; 
    public byte Alive  get; set; 

当我调用DB.add(SampleEntity) 添加然后DB.SaveChanges() 时发生的事情是在alive 属性上,我传递0 它在保存时更改为1 现在数据库上的数据类型是微小的int,应该允许0 - 255由于某种原因,它不接受 0。

【问题讨论】:

问题将出在其他地方。您用于查看 db cobtents 的工具不同步或正在修改您的实体 【参考方案1】:

简答

你忘了给 TestEntity 一个主键。

说明

TestEntity 没有主键。由于缺少它,Entity Framework 假定属性Alive 是应该包含主键的属性。保存时会自动生成主键值。

您可以通过添加第二个 TestEntity 来验证这一点。 Alive 的值会发生什么变化?

为您的实体框架定义标识符时,请考虑follow the conventions:对集合使用复数名词,对集合中的元素使用单数名词。

因此,如果您有一个包含 Products、Customers、Orders 等的数据库,那么您将拥有 Product、Customer、Order 类和表 Products、Customers、Orders。每个客户都有零个或多个订单,因此客户有一个属性订单(复数)。每个订单都是一个客户的订单,所以订单有一个属性客户(单数)。

通过遵循约定,您不需要告诉实体框架很多。但是,如果您已经有一个现有的数据库,并且您的表和表中的列的名称与约定所建议的不同,则需要告诉实体框架。

另一个建议:您的 TestEntity 代表您的 TestEntities 表中的一行。 TestEntity 的非虚拟属性表示表的列。虚拟属性表示表之间的关系(一对多,多对多,...)

因此,让 TestEntity 成为一个简单直接的 POCO:一个只有 get/set 的类。 不要添加不仅仅只是获取/设置的方法或属性

回到你的问题

public class Test

    public int Id get; set;            // Primary key

    public string Relation  get; set; 
    public byte? Age  get; set; 
    public byte Alive  get; set; 

顺便问一下,你确定 Alive 不是布尔值吗?我可以想象你是活着的,或者不是活着的,但是活着 = 4 是什么意思?考虑使用正确描述其含义的标识符。未来的读者会因此而称赞你。

虚拟属性表示与其他表的关系。例如,如果每个 Test 有零个或多个 TestResult(一对多关系),则添加以下属性:

    public virtual ICollection<TestResult> TestResults get; set;

这是ICollection&lt;TestResult&gt;,而不是List&lt;TestResult&gt;。毕竟,TestResults[4] 是什么意思?接口 ICollection 包含足够的属性来添加/删除/更改此测试的测试结果。

如果这个Test是一个Student的Test,那么它和Student之间是一对多的关系:每个Student都有零个或多个Tests,每个Test都是一个Student的Test,也就是外来的Student键是指。

添加以下属性:

public int StudentId get; set;      // a real column in the table: non-virtual
public Student Student get; set;    // represents a relation: virtual

当然,在Student类中你需要添加:

public virtual ICollection<Test> Tests get; set;



class MyDbContext : DbContext

    public DbSet<Test> Tests get; set;
    public DbSet<TestResult> TestResults get; set;
    public DbSet<Student> Students get; set;

由于我遵循约定,实体框架将能够检测表、表中的列、列的功能(主/外键)以及表之间的关系。如果您决定偏离约定,您将只需要属性或流畅的 API。但这不在你的问题范围内。

【讨论】:

其实有一个主键

以上是关于使用 LINQ (C#) 时 SQL Server 中的 TinyInt 数据类型不保存 0 整数的主要内容,如果未能解决你的问题,请参考以下文章

C#中如何用Linq在SQL Server的表中多列检索多个关键字

如何使用 LINQ to SQL 连接到 SQL Server?

在 C# 中使用 LINQ 方法语法 (LINQ to SQL) 时发生异常

LINQ to SQL 调用 SQL Server 的系统函数

使用带有 Linq to Sql 的 Sql Server 唯一标识符/更新日期列 - 最佳方法

在运行时将实体对象添加到 LINQ-to-SQL 数据上下文 - SQL、C#(WPF)