sqlite.net表子表上的条件

use*_*857 4 c# sqlite.net xamarin.forms sqlite-net-extensions

我正在使用Xamarin表单,SQLite.net和SQLitenet扩展,我无法弄清楚为什么我希望简单的东西不起作用.

我有两节课

public class MeasurementInstanceModel
{
    public MeasurementInstanceModel ()
    {
    }

    [PrimaryKey]
    [AutoIncrement]
    public int Id {
        get;
        set;
    }

    [ForeignKey(typeof(MeasurementDefinitionModel))]
    public int MeasurementDefinitionId {
        get;
        set;
    }

    [ManyToOne(CascadeOperations = CascadeOperation.CascadeRead)]
    public MeasurementDefinitionModel Definition {
        get;
        set;
    }

    [ForeignKey(typeof(MeasurementSubjectModel))]
    public int MeasurementSubjectId {
        get;
        set;
    }

    [ManyToOne(CascadeOperations = CascadeOperation.CascadeRead)]
    public MeasurementSubjectModel Subject {
        get;
        set;
    }

    public DateTime DateRecorded {
        get;
        set;
    }

    [OneToMany(CascadeOperations = CascadeOperation.All)]
    public List<MeasurementGroupInstanceModel> MeasurementGroups {
        get;
        set;
    }
}
Run Code Online (Sandbox Code Playgroud)

public class MeasurementSubjectModel
{


    [PrimaryKey]
    [AutoIncrement]
    public int Id {
        get;
        set;
    }
    public string Name {
        get;
        set;
    }

    [OneToMany (CascadeOperations = CascadeOperation.All)]
    public List<MeasurementInstanceModel> MeasurementInstances {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

我只是尝试执行以下查询,它总是失败.

db.Table<MeasurementInstanceModel>().Where(w => w.Subject.Name == avariable);
Run Code Online (Sandbox Code Playgroud)

我得到了这个例外

System.Diagnostics.Debugger.Mono_UnhandledException(EX = {System.Reflection.TargetInvocationException:异常已被调用的目标抛出---> System.NullReferenceException:在SQLite.Net对象引用不设置为一个对象的一个实例.TableQuery 1[MeasureONE.MeasurementInstanceModel].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List1 queryArgs)[0x00000] in:0 at SQLite.Net.TableQuery 1[MeasureONE.MeasurementInstanceModel].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List1 queryArgs)[0x00000] in:0 at SQLite.Net.TableQuery 1[MeasureONE.MeasurementInstanceModel].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List1 queryArgs)[0x00000] in:0 at SQLite.Net.TableQuery 1[MeasureONE.MeasurementInstanceModel].GenerateCommand (System.String selectionList) [0x00000] in <filename unknown>:0 at SQLite.Net.TableQuery1 [MeasureONE .MeetmentInstanceModel] .GetEnumerator()[0x00000] in:0 at System.Collections.Generic.List 1[MeasureONE.MeasurementInstanceModel].AddEnumerable (IEnumerable1 enumerable)[0x00000] in:0 at System.Collections.Generic.List 1[MeasureONE.MeasurementInstanceModel]..ctor (IEnumerable1 collection)[0x00000] in:0 at System. Linq.Enumerable.ToList [MeasurementInstanceModel](IEnumerable的1 source) [0x00000] in <filename unknown>:0 at MeasureONE.Repository1 [MeasureONE.MeasurementInstanceModel] .GetAll [DATETIME](System.Linq.Expressions.Expression 1 predicate, System.Linq.Expressions.Expression1 ORDERBY,可空1 descending, Nullable1次跳跃,可空1 count) [0x00094] in /Users/jean-sebastiencote/MeasureONE/MeasureONE/Models/Repository/Repository.cs:48 at MeasureONE.Repository1 [MeasureONE.MeasurementInstanceModel] .GetAllWithChildren [DATETIME](系统.Linq.Expressions.Expression 1 predicate, System.Linq.Expressions.Expression1 orderBy,Nullable 1 descending, Nullable1 skip,Nullable 1 count) [0x00009] in /Users/jean-sebastiencote/MeasureONE/MeasureONE/Models/Repository/Repository.cs:54 at MeasureONE.MeasurementListViewModel.Load (System.Linq.Expressions.Expression1 pred,Nullable 1 skip, Nullable1 c 'mount)[0x00049]在/Users/jean-sebastiencote/MeasureONE/MeasureONE/ViewModels/MeasurementListViewModel.cs:42在MeasureONE.MeasurementListViewModel.Load(MeasureONE.FilterViewModel滤波器)[0x000cf]在/用户/牛仔-sebastiencote/MeasureONE/MeasureONE /ViewModels/MeasurementListViewModel.cs:34在MeasureONE.MeasurementListViewModel.m__1(GalaSoft.MvvmLight.Messaging.NotificationMessage`1 MSG)[0x00007]在/Users/jean-sebastiencote/MeasureONE/MeasureONE/ViewModels/MeasurementListViewModel.cs:21在(包装器管理到本机)System.Reflection.MonoMethod:InternalInvoke(System.Reflection.MonoMethod,对象,在对象System.Reflection.MonoMethod.Invoke [],System.Exception的&)(System.Object的物镜,的BindingFlags invokeAttr,系统. Reflection.Binder binder,System.Object []参数,System.Globalization.CultureInfo文化)[0x00000] in:0 ---内部异常堆栈跟踪结束---

正如您从堆栈跟踪中看到的那样,我在代码中还有一些内容,例如order by.但是这一切都很好,只要我在儿童桌上没有条件.

red*_*t84 8

SQLite-Net Extensions不添加任何查询功能(至少到现在为止).这意味着您无法在查询时访问关系,因为该对象需要JOIN才能执行.这就是你获得的原因NullReferenceException.

您需要手动执行JOIN.替换此代码:

db.Table<MeasurementInstanceModel>().Where(w => w.Subject.Name == avariable);
Run Code Online (Sandbox Code Playgroud)

有了这个:

var result = conn.Query<MeasurementInstanceModel>(
    "SELECT * " +
    "FROM MeasurementInstanceModel AS it " +
    "JOIN MeasurementSubjectModel AS sb " +
    "ON it.MeasurementSubjectId == sb.Id " +
    "WHERE sb.Name == ?", avariable);
Run Code Online (Sandbox Code Playgroud)

自动创建这种查询非常复杂,并且计划在不久的将来不再支持SQLite-Net Extensions.

使用SQLite-Net Extension关系的另一个选项是使用GetAllWithChildren方法过滤所需的主题,然后浏览关系以获取实例:

var subjects = conn.GetAllWithChildren<MeasurementSubjectModel>(s => s.Name == avariable);
var result = subjects.Select(s => s.MeasurementInstances).Distinct().ToList();
Run Code Online (Sandbox Code Playgroud)

这样您就不必手动键入JOIN并且结果完全相同,但是此选项会遇到N + 1问题,因此可能会受到一些性能损失.

希望能帮助到你.