Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When Using a Custom Type as a Primary Key,The Overloaded == Operator for This Custom Type,Should Perhaps Provide More Robust Coding Guidance Related to Nullable Reference Types #35376

Open
UserName-Lotus opened this issue Dec 23, 2024 · 0 comments

Comments

@UserName-Lotus
Copy link

UserName-Lotus commented Dec 23, 2024

Title

When Using a Custom Type as a Primary Key
The Overloaded == Operator for This Custom Type
Should Perhaps
Provide More Robust Coding Guidance Related to Nullable Reference Types

Phenomenon

When Running the Following Code
Near the Overloaded == Operator Method
An Error is Triggered:
System.NullReferenceException: "Object reference not set to an instance of an object."

Analysis and Opinion

This Situation
Is Equivalent to Ef Core Requiring That
The left and right Parameters of the Overloaded == Operator Method
Must Use Nullable Reference Types
And Not Non-nullable Reference Types

Ef Core Might Be Responsible for Detecting When
The Overloaded == Operator Method
Uses Non-nullable Reference Types as Parameters
Which Can Potentially Lead to Errors

Or
There Should Be Some Out-of-the-box (Present by Default) Solution
To Warn About the Existence of Such Code That Could Cause Errors

标题

当把自定义类型作为主键时
对于该自定义类型的==运算符重载方法
或许应该
提供,与可空引用类型,相关的
更完善的编码提示

现象

当运行下面的代码的
在==运算符重载方法的附近
会触发报错
System.NullReferenceException:“Object reference not set to an instance of an object.”

分析和意见

这种情况
相当于,Ef Core要求
==运算符重载方法,的left和right参数
必须使用,可空的,引用类型
不允许使用,不可空的,引用类型

Ef Core 可能有责任,识别到
==运算符重载方法
使用了,不可空的,引用类型,作为参数
进而,有一定概率将引发报错

或者
应该,提供某种开箱即用(默认情况下就有)的方案
来提示,这种可能引发报错的代码,的存在

Code

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

namespace AConsoleApp;

internal class Program
{
    class MyDbContext : DbContext
    {
        public DbSet<Student> Students { get; private set; }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer
                ("Server=localhost\\SqlServerA;Database=MyDbContext;User=sa;Password=abcd;TrustServerCertificate=True;");
        }
        protected override void ConfigureConventions
            (ModelConfigurationBuilder modelConfigurationBuilder)
        {
            modelConfigurationBuilder.Properties<StudentId>().HaveConversion<StudentIdConverter>();
        }
    }
    static void Main(string[] args)
    {
        {
            using var db = new MyDbContext();
            db.Database.EnsureDeleted();
            db.Database.EnsureCreated();
        }
        {
            using var db = new MyDbContext();
            var studentA = new Student("Tom");
            db.Students.Add(studentA);
            db.SaveChanges();
        }
    }
    [PrimaryKey(nameof(Id))]
    class Student
    {
        public StudentId Id { get; private set; }
        public string Name { get; set; }
        public Student(string name)
        {
            this.Id = new();
            this.Name = name;
        }
    }
    public class StudentIdConverter : ValueConverter<StudentId, long>
    {
        public StudentIdConverter()
            : base(
                v => v.Ticks,
                v => new StudentId(v))
        {
        }
    }
    public partial class StudentId
    {
        public long Ticks { get; private set; }
        public StudentId()
        {
            this.Ticks = DateTime.Now.Ticks;
        }
        public StudentId(long ticks)
        {
            this.Ticks = ticks;
        }
        // System.NullReferenceException:“Object reference not set to an instance of an object.”
        public static bool operator ==(StudentId left, StudentId right)
            => left.Ticks == right.Ticks;
        public static bool operator !=(StudentId left, StudentId right)
            => left.Ticks != right.Ticks;
    }

}
@UserName-Lotus UserName-Lotus changed the title When using a custom type as the primary key, there may need to be more comprehensive coding hints for the overloading method of the == operator for that custom type. When Using a Custom Type as a Primary Key,The Overloaded == Operator for This Custom Type,Should Perhaps Provide More Robust Coding Guidance Related to Nullable Reference Types Dec 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant