簡體   English   中英

sqlite.net表子表上的條件

[英]sqlite.net table where condition on a child table

我正在使用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:調用目標已拋出異常.---> System.NullReferenceException:對象引用未設置為SQLite.Net上的對象實例.TableQuery 1[MeasureONE.MeasurementInstanceModel].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List 1 queryArgs)[0x00000] in:0 at SQLite.Net.TableQuery 1[MeasureONE.MeasurementInstanceModel].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List 1 queryArgs)[0x00000] in:0 at SQLite.Net.TableQuery 1[MeasureONE.MeasurementInstanceModel].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List 1 queryArgs)[0x00000] in:0 in SQLite.Net.TableQuery 1[MeasureONE.MeasurementInstanceModel].GenerateCommand (System.String selectionList) [0x00000] in <filename unknown>:0 at SQLite.Net.TableQuery 1 [MeasureONE.MeasurementInstanceModel] .GetEnu merator()[0x00000] in:0 at System.Collections.Generic.List 1[MeasureONE.MeasurementInstanceModel].AddEnumerable (IEnumerable 1 enumerable)[0x00000] in:0 at System.Collections.Generic.List 1[MeasureONE.MeasurementInstanceModel]..ctor (IEnumerable 1 collection)[0x00000] in:0 in 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 descending, Nullable 1 skip,Nullable 1 count) [0x00094] in /Users/jean-sebastiencote/MeasureONE/MeasureONE/Models/Repository/Repository.cs:48 at MeasureONE.Repository 1 [MeasureONE.MeasurementInstanceModel] .GetAllWithChildren [DateTime](System.Linq.Expressions.Expression 1 predicate, System.Linq.Expressions.Expression 1 orderBy,Nullable 1 descending, Nullable 1 count) [0x00009] in /Users/jean-sebastiencote/MeasureONE/MeasureONE/Models/Repository/Repository.cs:54 at MeasureONE.MeasurementListViewModel.Load (System.Linq.Expressions.Expression 1 descending, Nullable 1 skip,Nullable 1 count) [0x00009] in /Users/jean-sebastiencote/MeasureONE/MeasureONE/Models/Repository/Repository.cs:54 at MeasureONE.MeasurementListViewModel.Load (System.Linq.Expressions.Expression 1 count) [0x00009] in /Users/jean-sebastiencote/MeasureONE/MeasureONE/Models/Repository/Repository.cs:54 at MeasureONE.MeasurementListViewModel.Load (System.Linq.Expressions.Expression 1 pred,Nullable 1 skip, Nullable 1 count)[0x00049] in / Users / jean-sebastiencote /MeasureONE/MeasureONE/ViewModels/MeasurementListViewModel.cs:42位於MeasureONE.MeasurementListViewModel的/Users/jean-sebastiencote/MeasureONE/Measureone/ViewModels/MeasurementListViewModel.cs:34中的MeasureONE.MeasurementListViewModel.Load(MeasureONE.FilterViewModel過濾器)[0x000cf] .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 :System.Reflection.MonoMethod.Invoke中的InternalInvoke(System.Reflection.MonoMethod,object,object [],System.Exception&)(System.Object obj,BindingFlags invokeAttr,System.Reflection.Binder binder,System.Object []參數, System.Globalization.CultureInfo 文化)[0x00000] in:0 ---內部異常堆棧跟蹤結束---

正如您從堆棧跟蹤中看到的那樣,我在代碼中還有一些內容,例如order by。 但是這一切都很好,只要我在兒童桌上沒有條件。

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問題 ,因此可能會受到一些性能損失。

希望能幫助到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM