C# NullReferenceException查询连接字符串属性上具有Where的SQLite数据库

C# NullReferenceException查询连接字符串属性上具有Where的SQLite数据库,c#,android,sqlite-net-extensions,C#,Android,Sqlite Net Extensions,我正在尝试使用以下代码选择一条记录: Location item = connection .Table<Location>() .Where(l => l.Label.Equals(label)) .FirstOrDefault(); 位置项=连接 .表( 其中(l=>l.Label.Equals(Label)) .FirstOrDefault(); 这导致: System.NullReferenceException:对象引用未设置为对象的实例。 当我在不同

我正在尝试使用以下代码选择一条记录:

Location item = connection
  .Table<Location>()
  .Where(l => l.Label.Equals(label))
  .FirstOrDefault();
位置项=连接
.表(
其中(l=>l.Label.Equals(Label))
.FirstOrDefault();
这导致:

System.NullReferenceException:对象引用未设置为对象的实例。

当我在不同的属性(邮政编码)上尝试相同的方法时,如果找不到任何记录,也可以正常工作

Location item = connection
  .Table<Location>()
  .Where(l => l.Postcode.Equals(label))
  .FirstOrDefault();
位置项=连接
.表(
.其中(l=>l.邮政编码等于(标签))
.FirstOrDefault();
这是Location类:

// These are the Locations where the Stock Take Sessions are done
public class Location : DomainModels, IComparable<Location>
{
    [JsonProperty("id"), PrimaryKey]
    public int Id { get; set; }
    public string Name { get; set; }
    public string Street { get; set; }
    public int Number { get; set; }
    public string Postcode { get; set; }
    public string City { get; set; }
    public bool Completed { get; set; }

    [Ignore] // Removing this does not have an impact on the NullReferenceException
    public string Label => $"{Name ?? ""} - ({Postcode ?? ""})";

    public int CompareTo(Location other)
    {
        return Name.CompareTo(other.Name);
    }

    // Navigation property
    // One to many relationship with StockItems
    [OneToMany(CascadeOperations = CascadeOperation.All), Ignore]
    public List<StockItem> StockItems { get; set; }

    // Specify the foreign key to StockTakeSession
    [ForeignKey(typeof(StockTakeSession))]
    public int StockTakeSessionId { get; set; }

    // One to one relationship with StockTakeSession
    [OneToOne]
    public StockTakeSession StockTakeSession { get; set; }

}
//这些是完成盘点会话的位置
公共类位置:DomainModels,IComparable
{
[JsonProperty(“id”),PrimaryKey]
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串Street{get;set;}
公共整数{get;set;}
公共字符串邮政编码{get;set;}
公共字符串City{get;set;}
公共bool已完成{get;set;}
[忽略]//删除此项不会对NullReferenceException产生影响
公共字符串标签=>$“{Name???”}-({Postcode???”})”;
公共内部比较(位置其他)
{
返回Name.CompareTo(其他.Name);
}
//导航属性
//与库存项目的一对多关系
[OneToMany(CascadeOperations=CascadeOperation.All),忽略]
公共列表StockItems{get;set;}
//指定StockTakeSession的外键
[ForeignKey(类型(盘点会议))]
public int StockTakeSessionId{get;set;}
//与盘点会议的一对一关系
[OneToOne]
公共盘点会话盘点会话{get;set;}
}
我做错了什么


谢谢你的建议

您的where过滤器位于
标签上的数据存储中,但是
您在类
位置上的标记
IgnoreAttribute
装饰了
标签
属性。这意味着在实体被物化到内存中并且您不能在数据存储中对其执行任何操作之前,
标签
属性将不会被设置

.Where(l => l.Label.Equals(label))
修复 有一些选择

  • 您可以将其设置为computed,并使用相同的逻辑在存储中创建一个computed列。这涉及到直接在RDBMS管理器中手动更改表模式或编辑迁移脚本。属性被标记为
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    (如果使用属性,上面的代码就是属性)
  • 您可以将
    Where
    更改为在商店中找到的组成
    标签的属性上进行筛选。ie:
    。其中(l=>l.Postcode.Equals(Postcode)和&l.Name.Equals(Name))
  • 您可以将特定过滤器之前的所有内容具体化到内存中,然后应用过滤器。如果在该点之前的所有内容都会导致大量记录,则不建议这样做。例如,使用下面的代码,如果表很大,您将检索单个记录的所有内容

    Location item = connection
      .Table<Location>()
      .AsEnumerable()
      .Where(l => l.Label.Equals(label))
      .FirstOrDefault();
    
    位置项=连接
    .表(
    .可计算的()
    其中(l=>l.Label.Equals(Label))
    .FirstOrDefault();
    

编辑 [忽略]//删除此项不会对NullReferenceException产生影响


不,除非您遍历并将同名列添加到现有架构中,并且用所有数据填充该列,否则不应该这样做。(或在架构中创建一个同名的计算列)

连接中的
位置之一
。表
具有
标签
=null。这就是为什么你有这个问题。您需要确保
连接中的所有项。表
都设置了Label属性。可能存在@ChetanRanpariya的重复项:我检查了数据库,没有任何记录缺少de name或邮政编码。谢谢@Igor。你能给我看一下你建议的第一个和第三个子弹的密码吗?我是新手,完全理解你的意思,一个代码示例可能会有所帮助。谢谢@罗伯特:完成了。我没有为如何在数据存储中创建计算列添加代码,但您可以通过搜索在线找到它。我选择了第一个选项,但这似乎与实体框架相关。我说得对吗?我将SQLite Net与SQLite.Net.Attributes和SQLiteNetExtensions.Attributes一起使用。两者都不支持[DatabaseGenerated]属性。@Robert-我对
SQLLite
几乎一无所知,但如果rdbms支持计算列,它应该可以工作。该属性与提供者无关:没问题,谢谢您抽出时间。为了解决这个问题,我将在记录插入数据库时生成标签。