sqlite.net表子表上的条件

时间:2014-09-07 21:23:37

标签: c# xamarin.forms sqlite-net-extensions sqlite.net

我使用的是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;
    }
}

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;}
}

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

db.Table<MeasurementInstanceModel>().Where(w => w.Subject.Name == avariable);

我得到了这个例外

  

System.Diagnostics.Debugger.Mono_UnhandledException(ex = {System.Reflection.TargetInvocationException:调用目标已抛出异常.---&gt; System.NullReferenceException:未将对象引用设置为对象的实例     在SQLite.Net.TableQuery 1[MeasureONE.MeasurementInstanceModel].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List 1 queryArgs)[0x00000] in:0     在SQLite.Net.TableQuery 1[MeasureONE.MeasurementInstanceModel].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List 1 queryArgs)[0x00000] in:0     在SQLite.Net.TableQuery 1[MeasureONE.MeasurementInstanceModel].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List 1 queryArgs)[0x00000] in:0     在SQLite.Net.TableQuery 1[MeasureONE.MeasurementInstanceModel].GenerateCommand (System.String selectionList) [0x00000] in <filename unknown>:0 at SQLite.Net.TableQuery 1 [MeasureONE.MeasurementInstanceModel] .GetEnumerator()[0x00000] in:0     at System.Collections.Generic.List 1[MeasureONE.MeasurementInstanceModel].AddEnumerable (IEnumerable 1 enumerable)[0x00000] in:0     在System.Collections.Generic.List 1[MeasureONE.MeasurementInstanceModel]..ctor (IEnumerable 1集合)[0x00000] in:0     at System.Linq.Enumerable.ToList [MeasurementInstanceModel](IEnumerable 1 source) [0x00000] in <filename unknown>:0 at MeasureONE.Repository 1 [MeasureONE.MeasurementInstanceModel] .GetAll [DateTime](System.Linq.Expressions.Expression 1 predicate, System.Linq.Expressions.Expression 1 orderBy,Nullable {{1} } 1 skip,Nullable 1 descending, Nullable 1 [MeasureONE.MeasurementInstanceModel] .GetAllWithChildren [DateTime](System.Linq.Expressions.Expression 1 count) [0x00094] in /Users/jean-sebastiencote/MeasureONE/MeasureONE/Models/Repository/Repository.cs:48 at MeasureONE.Repository 1 orderBy,Nullable 1 predicate, System.Linq.Expressions.Expression 1 skip,Nullable {{1 1个pred,Nullable 1 descending, Nullable 1个计数)[0x00049] /Users/jean-sebastiencote/MeasureONE/MeasureONE/ViewModels/MeasurementListViewModel.cs:42     在MeasureONE.MeasurementListViewModel.Load(MeasureONE.FilterViewModel过滤器)[0x000cf] /Users/jean-sebastiencote/MeasureONE/MeasureONE/ViewModels/MeasurementListViewModel.cs:34     在MeasureONE.MeasurementListViewModel.m__1(GalaSoft.MvvmLight.Messaging.NotificationMessage`1 msg)[0x00007] in /Users/jean-sebastiencote/MeasureONE/MeasureONE/ViewModels/MeasurementListViewModel.cs:21     at(wrapper managed-to-native)System.Reflection.MonoMethod:InternalInvoke(System.Reflection.MonoMethod,object,object [],System.Exception&amp;)     在System.Reflection.MonoMethod.Invoke(System.Object obj,BindingFlags invokeAttr,System.Reflection.Binder binder,System.Object [] parameters,System.Globalization.CultureInfo culture)[0x00000] in:0     ---内部异常堆栈跟踪结束---

从堆栈跟踪中可以看出,代码中还有一些内容,例如order by。但这一切都很好,只要我没有儿童餐桌上的条件。

1 个答案:

答案 0 :(得分:7)

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

的原因

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

db.Table<MeasurementInstanceModel>().Where(w => w.Subject.Name == avariable);

有了这个:

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

自动创建此类查询非常复杂,并且计划在不久的将来不再支持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();

这样您就不必手动键入JOIN,结果完全相同,但是此选项会受N+1 issue的影响,因此可能会受到一些性能损失。

希望它有所帮助。