亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Lambda 不能進行 Int16 比較嗎?

Lambda 不能進行 Int16 比較嗎?

C#
慕尼黑5688855 2023-09-09 16:34:42
lambda expression我的 C# (.NET 4.7.1) 代碼中有以下內容:DataRow[] skmRows = dtSKM.AsEnumerable().Where(x =>    x.Field<int>("NDRAWING1").Equals(NDRAWING1) &&    x.Field<Int16>("NDRAWING2").Equals(NDRAWING2)    ).ToArray();一切都會編譯,并且在運行時不會引發異常。問題是上面的 lambda 表達式應該得到結果,但事實并非如此。我停在斷點處并驗證DataRows應該已經發生匹配。然后我將這個表達式復制到Immediate窗口中VS2017并運行它——它確實獲得了匹配的數據行。啥??然后我就想知道這一點Int16。MSSQL 中的相關列是 a SMALLINT,它映射到 C# 中的 INT16。為了好玩,我將 sql server 中的數據類型從smallint更改為int,并因此更改了我的lambda:DataRow[] skmRows = dtSKM.AsEnumerable().Where(x =>    x.Field<int>("NDRAWING1").Equals(NDRAWING1) &&    x.Field<int>("NDRAWING2").Equals(NDRAWING2)    ).ToArray();...它成功了?。ㄎ野搭A期得到了匹配的行。)這讓我得出結論,.NET 中存在一個錯誤,運行時無法正確評估 Int16 與smallint sql server 列值的比較。除了bug還有解釋嗎?我猜這對任何人來說都應該很容易重現。啟動一個 lambda 來匹配 MSSQL 中的 SMALLINT 列,看看會發生什么。
查看完整描述

1 回答

?
滄海一幻覺

TA貢獻1824條經驗 獲得超5個贊

確實,smallint映射到int16又名Short。您可以在adonet 服務器數據類型映射處驗證它。至于發生了什么,請檢查 int16 equals 的文檔:“如果 obj 是 Int16 的實例并且等于該實例的值,則為 true;否則為 false。”?。

變量NDRAWING2也需要是int16 。在Javascript中,有運算符“===”來表示值和類型必須相同。


通過正確的抽象,使用 Microsoft.EntityFrameworkCore.InMemory 2.2.6 和 NUnit 3.2,我將:

  • 在內存數據庫上下文中創建

  • 添加上下文到服務

  • 使用服務添加一些數據并將它們存儲到數據庫

  • 驗證它在新上下文中是否有一些數據

  • 使用服務查找我想要的數據

  • 驗證它確實找到了數據

代碼示例:

class Program

{

? ? static void Main(string[] args)

? ? {

? ? ? ? var options = new DbContextOptionsBuilder<DtSkmContext>()

? ? ? ? ? ? .UseInMemoryDatabase(databaseName: "Add_writes_to_database")

? ? ? ? ? ? .Options;


? ? ? ? using (var context = new DtSkmContext(options))

? ? ? ? {

? ? ? ? ? ? var service = new DtSkmService(context);

? ? ? ? ? ? service.Add(3, 7);

? ? ? ? ? ? context.SaveChanges();

? ? ? ? }


? ? ? ? using (var context = new DtSkmContext(options))

? ? ? ? {

? ? ? ? ? ? Assert.That(context.DtSkm.Count(), Is.EqualTo(1));


? ? ? ? ? ? var service = new DtSkmService(context);

? ? ? ? ? ? var result = service.Find(3, 7);


? ? ? ? ? ? Assert.That(result, Is.Not.Null);

? ? ? ? }

? ? }

}

服務


public class DtSkmService

{

? ? private DtSkmContext _context;


? ? public DtSkmService(DtSkmContext context)

? ? {

? ? ? ? _context = context;

? ? }


? ? public void Add(int ndrawing1, Int16 ndrawing2)

? ? {

? ? ? ? var dtSkm = new DtSkmDto { Ndrawing1 = ndrawing1, Ndrawing2 = ndrawing2 };

? ? ? ? _context.DtSkm.Add(dtSkm);

? ? ? ? _context.SaveChanges();

? ? }


? ? public IEnumerable<DtSkmDto> Find(int first, Int16 second)

? ? {

? ? ? ? return _context.DtSkm

? ? ? ? ? ? .Where(b => b.Ndrawing1.Equals(first) && b.Ndrawing2.Equals(second))

? ? ? ? ? ? .OrderBy(b => b.Ndrawing1)

? ? ? ? ? ? .ToList();

? ? }

}

和 dto 和上下文


public class DtSkmDto

{

? ? public int Id { get; set; }

? ? [Required]

? ? public int Ndrawing1 { get; set; }

? ? [Required]

? ? public Int16 Ndrawing2 { get; set; }

}

public class DtSkmContext : DbContext

{

? ? public DtSkmContext()

? ? {

? ? }

? ? public DtSkmContext(DbContextOptions<DtSkmContext> options) : base(options)

? ? {

? ? }

? ? public DbSet<DtSkmDto> DtSkm { get; set; }

}

雖然這使用 EF core 和內存數據庫,但它展示了一種實現方法。根據您的情況,您可以進行一些小的更改:


var data = dtSKM.AsEnumerable().ToList();

DataRow[] skmRows = data.Where(x =>

? ?x.Field<int>("NDRAWING1").Equals(NDRAWING1) &&

? ?x.Field<Int16>("NDRAWING2").Equals(NDRAWING2)

? ?).ToArray();

您可以使用調試器驗證數據實例類型/值。你的假設之一不成立,它不是“.NET 中的錯誤”。


查看完整回答
反對 回復 2023-09-09
  • 1 回答
  • 0 關注
  • 122 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號