You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中使属性唯一?以City类Name属性为例

实现City类Name属性唯一性的方案

1. 数据库层面添加唯一约束(最可靠)

数据库约束是防止重复数据的最后一道防线,无论通过何种方式操作数据,数据库都会拦截重复值。

用EF Core Fluent API配置

如果使用Entity Framework Core,可在DbContext的OnModelCreating方法中配置唯一索引:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // 基础唯一索引配置
    modelBuilder.Entity<City>()
        .HasIndex(c => c.Name)
        .IsUnique()
        .HasDatabaseName("IX_Cities_Name");

    // 若需忽略大小写(如"Beijing"和"beijing"视为重复),针对不同数据库适配:
    // SQL Server 配置不区分大小写的排序规则
    modelBuilder.Entity<City>()
        .HasIndex(c => c.Name)
        .IsUnique()
        .HasDatabaseName("IX_Cities_Name")
        .HasCollation("SQL_Latin1_General_CP1_CI_AS");

    // PostgreSQL 可改用citext类型实现大小写不敏感
    // modelBuilder.Entity<City>()
    //     .Property(c => c.Name)
    //     .HasColumnType("citext");
    // 再配置唯一索引
}

手动创建数据库约束(非EF场景)

直接执行SQL语句添加约束:

-- SQL Server
CREATE UNIQUE NONCLUSTERED INDEX IX_Cities_Name ON Cities (Name COLLATE SQL_Latin1_General_CP1_CI_AS);

-- PostgreSQL
CREATE UNIQUE INDEX IX_Cities_Name ON Cities (LOWER(Name));

-- MySQL
CREATE UNIQUE INDEX IX_Cities_Name ON Cities (Name) COLLATE utf8mb4_general_ci;

2. 业务逻辑层提前校验

在添加/更新City对象前,先查询数据库是否存在同名记录,避免触发数据库异常:

public async Task<bool> AddCityAsync(City newCity)
{
    // 检查是否存在同名城市,支持大小写忽略
    var existingCity = await _dbContext.Cities
        .FirstOrDefaultAsync(c => c.Name.Equals(newCity.Name, StringComparison.OrdinalIgnoreCase));

    if (existingCity != null)
    {
        throw new InvalidOperationException($"名称为{newCity.Name}的城市已存在");
        // 也可返回false,由上层处理错误逻辑
        // return false;
    }

    _dbContext.Cities.Add(newCity);
    await _dbContext.SaveChangesAsync();
    return true;
}

3. 数据注解方式(EF Core有限支持)

.NET 5+支持用[Index]注解快速配置,但灵活性不如Fluent API:

public class City: MyClass1
{
    [MaxLength(255)]
    [Index(IsUnique = true, Name = "IX_Cities_Name")]
    public required string Name { get; set; }
}

注:此方式无法直接配置大小写不敏感,仍推荐使用Fluent API。

4. 并发场景处理

多请求同时添加同名城市时,业务层校验可能出现竞态条件,需捕获数据库唯一约束异常并处理:

public async Task<bool> AddCityAsync(City newCity)
{
    try
    {
        _dbContext.Cities.Add(newCity);
        await _dbContext.SaveChangesAsync();
        return true;
    }
    catch (DbUpdateException ex)
    {
        // 针对SQL Server的唯一约束错误码(2601)做判断
        if (ex.InnerException is SqlException sqlEx && sqlEx.Number == 2601)
        {
            throw new InvalidOperationException($"名称为{newCity.Name}的城市已存在", ex);
        }
        throw; // 其他异常重新抛出
    }
}

内容的提问来源于stack exchange,提问作者Czesław Nowicki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 03:45:35