.NET中使用EF出現(xiàn)莫名字段缺失的問題

將.Net Framework中幾段使用EF相關的代碼移植到.NET的項目中,本想省點事,結果碰到莫名的故障,導致浪費不少時間來解決問題。
有兩個模型使用Scarffold-Context從數(shù)據(jù)庫中生成,示例如下(均作了適當簡化):

//用戶表模型
public partial class User
{
    public long Id { get; set; }

    public bool Enabled { get; set; }

    public string Login { get; set; } = null!;

    public string Password { get; set; } = null!;

    public string? Display { get; set; }
}
//角色表模型
public partial class Role
{
    public long Id { get; set; }

    public string Code { get; set; } = null!;

    public string Display { get; set; } = null!;

    public string? Description { get; set; }
}

//用戶與角色的關聯(lián)表模型
public partial class UserRole
{
    public long Id { get; set; }

    public long UserId { get; set; }

    public long RoleId { get; set; }
}

在使用下面的代碼進行Role表的所有數(shù)據(jù)的訪問時,突然出現(xiàn)如圖錯誤:

var roles = DbContext.Roles.ToList();
圖1. 奇怪的錯誤出現(xiàn):無效的列名'UserId'

然而,我們的Role模型里根本沒有涉及任何字段名為UserId,查詢SQL Server端,確實在執(zhí)行這一句查詢的時候,發(fā)送過去的查詢是:

SELECT [r].[ID], [r].[Code], [r].[Description], [r].[Display], [r].[UserId]
FROM [Role] AS [r]
ORDER BY [r].[Code]

看起來是EF在屁股后面加了個[r].[UserId]。
研究了很久,終于找到擴展模型User的分部類里,添加了一個屬性:

private ObservableCollection<Role> roles = [];
public ObservableCollection<Role> Roles
{
    get
    {
        if (roles.Count == 0)
        {
                var db = DbContext ?? AppHelper.DbContext;
                var rs = db.Roles.ToList();
                foreach (var r in rs)
                {
                    r.IsSelected = db.UserRoles.Any(p => p.UserId == Id && p.RoleId == r.Id);
                }

                var rls = rs.OrderBy(o => o.Code);

                foreach (var role in rls)
                {
                    roles.Add(role);
                }
        }

        return roles;
    }
}

要注意的是,在.Net Framework的EF中,并不需要明確聲明屬性與數(shù)據(jù)庫字段沒映射關系,而在.NET中,則需要用[NotMapped]明確聲明,這里忘記打上這個標記,所以Scaffold-Context在生成模型的時候,認為User跟Role有一個一對多的映射關系,所以它自動幫我“運作”了一下,給Role模型加了個隱式屬性(Shadow Property)UserId。解決辦法就是在這個屬性前面標上[NotMapped]就解決了。
如下所示:

private ObservableCollection<Role> roles = [];
[NotMapped]
public ObservableCollection<Role> Roles
{
    get
    {
        if (roles.Count == 0)
        {
                var db = DbContext;
                var rs = db.Roles.ToList();
                foreach (var r in rs)
                {
                    r.IsSelected = db.UserRoles.Any(p => p.UserId == Id && p.RoleId == r.Id);
                }

                var rls = rs.OrderBy(o => o.Code);

                foreach (var role in rls)
                {
                    roles.Add(role);
                }
        }

        return roles;
    }
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容