Realm Query中的错误(包装器托管到本机)Realms.NativeTable.get_string

时间:2016-07-19 20:57:43

标签: c# database xamarin realm

我试图在我的第一个Realm数据库上进行简单查询。我在尝试访问查询方法返回的对象的属性时收到错误。 我有两个问题:
 1.这个错误的含义是什么?我很难理解它...
 我正在以正确的方式进行查询吗?如果没有,我做错了什么?

错误日志:

Button button1 = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if(isToggleOn){
            //do one thing
        } else {
            //do other thing
        }      
    }
});

=====================================

[mono-rt] Stacktrace:

[mono-rt]   at <unknown> <0xffffffff>

[mono-rt]   at (wrapper managed-to-native) Realms.NativeTable.get_string >(Realms.TableHandle,intptr,intptr,intptr,intptr,bool&) <0x00057>

[mono-rt]   at Realms.RealmObject.GetStringValue (string) <IL 0x0009d, >0x00323>

[mono-rt]   at EasyVending.RCreditCard.get_holderName () <IL 0x0000e, 0x0006f>

[mono-rt]   at EasyVending.RealmManager.getCreditCard () [0x0001c] in /Users/Bernardo/Projects/EasyVending/EasyVending/DataBase/RealmManager.cs:75

[mono-rt]   at EasyVending.Android.CreditCartManagement.OnCreate (Android.OS.Bundle) [0x00111] in /Users/Bernardo/Projects/EasyVending/EasyVending.Android/Activities/CreditCartManagement.cs:89

[mono-rt]   at Android.Support.V4.App.FragmentActivity.n_OnCreate_Landroid_os_Bundle_ (intptr,intptr,intptr) <IL 0x00013, 0x000ff>

[mono-rt]   at (wrapper dynamic-method) object.13add723-97a5-4397-9c8a-e6fc23d98c3c (intptr,intptr,intptr) <IL 0x00017, 0x00043>

[mono-rt]   at (wrapper native-to-managed) object.13add723-97a5-4397-9c8a-e6fc23d98c3c (intptr,intptr,intptr) <IL 0x0001f, 0x00097>

[mono-rt] Attempting native Android stacktrace:

[mono-rt]  at ???+1 [0xbe903ac0]

[mono-rt]  at ???+1 [0x98f50ffc]

=================================================================

Got a SIGSEGV while executing native code. This usually indicates
[mono-rt] a fatal error in the mono runtime or one of the native libraries 
[mono-rt] used by your application.
[mono-rt]

[libc] Fatal signal 11 (SIGSEGV), code 1, fault addr 0x97b77168 in tid 9849 (vending_android)

当我尝试访问查询返回的RCreditCard对象的任何属性时发生错误:

public class RCreditCard : RealmObject {
    public string holderName { get; set; }
    public string bandeira { get; set; }
    public string digitos { get; set; }
    public string token { get; set; }
}

public class RealmManager {
    private string databaseName {
        get {
            return "PayBluDatabase.db";
        }
    }
    private string androidPath {
        get {
            return Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.Personal), databaseName);
        }
    }

    public Realm getRealm() {
        return Realm.GetInstance(androidPath);
    }

    public void closeRealm(Realm realm) {
        realm.Close();
    }

    public Transaction insertCreditCard(EasyVending.CreditCard creditCard) {
        var realm = getRealm();
        using(var transaction = realm.BeginWrite()) {
            var insertedCreditCard = realm.CreateObject<RCreditCard>();

            insertedCreditCard.holderName = creditCard.HolderName;
            insertedCreditCard.bandeira = creditCard.CreditCardBrand;
            insertedCreditCard.digitos = creditCard.MaskedCreditCardNumber;
            insertedCreditCard.token = creditCard.InstantBuyKey;

            transaction.Commit();
            closeRealm(realm);
            return transaction;
        }
    }

    public Transaction removeCreditCard() {
        var realm = getRealm();
        using(var transaction = realm.BeginWrite()) {
            realm.RemoveAll<RCreditCard>();
            transaction.Commit();
            closeRealm(realm);
            return transaction;
        }
    }

    public CreditCard getCreditCard() {
        var realm = getRealm();
        var rCreditCard = realm.All<RCreditCard>().First();
        closeRealm(realm);
        var creditCard = new CreditCard() {
            CreditCardBrand = rCreditCard.bandeira,
            MaskedCreditCardNumber = rCreditCard.digitos,
            HolderName = rCreditCard.holderName
        };
        return creditCard;
    }

    public bool hasCreditCard() {
        bool answer = false;
        var realm = getRealm();
        if(realm.All<RCreditCard>().Count() > 0) {
            answer = true;
        }
        closeRealm(realm);
        return answer;
    }
}

CreditCardBrand = rCreditCard.bandeira,

如果问题不够明确,请告诉我。

2 个答案:

答案 0 :(得分:1)

问题是,在尝试阅读rCreditCardgetCreditCard()上的属性之前,请先关闭该域。 Realm对象中的属性为零拷贝,它们直接访问数据库,因此只要关闭领域,对象就会变为无效。我们应该更好地处理这种情况,目前还不清楚。感谢您指出我们!

通常,您可能不希望像往常一样经常打开和关闭域,除非这些调用发生在不同的线程上。如果您坚持这样做,则应在事务Realm.Close()范围之外移动using次调用。就像现在一样,如果在事务期间抛出某些东西,它将被回滚,但你的领域不会像你期望的那样被关闭。

最后,通常没有必要拥有一个反映你RealmObject类的“普通”类。当然,在你的情况下,可能有原因,这里并不明显。通常,您可以直接使用RealmObject类。

答案 1 :(得分:1)

克里斯蒂安说什么; - )

只是为了澄清,如果你必须经常打开和关闭Realm,你可以用

来做
using (var realm = getRealm()) {
// your update and read logic
}