Xamarin.Android:SQLite-Net 扩展多对多 - 没有这样的 table,NULL 集合
Xamarin.Android: SQLite-Net Extensions many-to-many - no such table, NULL collection
我在 Visual Studio 2015 年的 Xamarin.Android 项目中安装了 SQLite-Net Extensions 包,我正在尝试在 Person
和 Event
实体。我关注了 the official documentation of the library,但我无法让它正常工作。
类 我创建了:
Person.cs:
[Table("People")]
public class Person
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
[ManyToMany(typeof(PersonEvent), CascadeOperations = CascadeOperation.All)]
public List<Event> Events { get; set; }
}
Event.cs:
[Table("Events")]
public class Event
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
public DateTime Date { get; set; }
public string Place { get; set; }
[ManyToMany(typeof(PersonEvent), CascadeOperations = CascadeOperation.All)]
public List<Person> Participants { get; set; }
}
个人Event.cs:
public class PersonEvent
{
[ForeignKey(typeof(Person))]
public int PersonId { get; set; }
[ForeignKey(typeof(Event))]
public int EventId { get; set; }
}
为了测试它,我删除了数据库文件以确保在设备上创建了一个干净的文件,然后尝试创建一个 Person
、一个 Event
,将两者都插入到先DB,然后将Event
分配给Person
,然后使用UpdateWithChildren
方法再次保存:
var dbFile = new File(Constants.DbFilePath);
dbFile.Delete();
var db = new SQLiteConnection(new SQLitePlatformAndroid(), Constants.DbFilePath);
db.CreateTable<Person>();
db.CreateTable<Event>();
db.CreateTable<PersonEvent>();
var event1 = new Event
{
Name = "Volleyball",
Date = new DateTime(2017, 06, 18),
Place = "Sports hall"
};
var person1 = new Person
{
Name = "A",
LastName = "B",
PhoneNumber = "123456789"
};
db.Insert(person1);
db.Insert(event1);
person1.Events = new List<Event> { event1 };
db.UpdateWithChildren(person1);
首先,我需要添加 CreateTable<PersonEvent>()
行,因为如果它不存在,我会得到异常:SQLite.Net.SQLiteException: no such table: PersonEvent
,但我认为我不必创建这个中间table 手动。 SQLite-Net Extensions 不应该以某种方式自动创建它吗?
添加此行后,event1
和 person1
的前两个插入工作正常(插入后两个实体都分配了 ID)。 person1
上的 Events
集合甚至创建了 Event
,它也设置了 Id:
但是,"opposite entity",在本例中 event1
有其 Participants
集合(列表 Person
)NULL
:
我尝试了所有方法,但没有任何效果。据我了解阅读 SQLite-Net Extensions 文档,它应该自动解决。我什至在集合中添加了这个 CascadeOperations = CascadeOperation.All
,但如您所见,它没有帮助。我还是做错了什么?
The Events collection on person1 has even the Event created, which also has Id set
您的 person1
对象具有您创建的事件列表。该集合包含一个 link 到您创建的 event1
对象。当您插入或更新数据库时,此事件集合未更新。当您将 Event 对象插入数据库时,您会发现它设置了 Id,因为列表包含相同的对象。
SQLite-NET Extensions 不是 [自动] 延迟加载解决方案(如 Entity Framework)。它只有在被告知时才会获取对象。使用 Get 方法从数据库中获取对象与 SQLite 已经做的没有任何不同。这是因为 SQLite-NET Extensions 不会改变该方法。但是它确实提供了像 GetWithChildren and FindWithChildren 这样的新方法。如果你想获得一个对象的子对象,你需要 SQLite-NET Extensions 提供的方法。
提供的示例也使用了这些方法:
// Get the object and the relationships
var storedValuation = db.GetWithChildren<Valuation>(valuation.Id);
if (euro.Symbol.Equals(storedValuation.Stock.Symbol)) {
Debug.WriteLine("Object and relationships loaded correctly!");
}
您也不希望对象从 Person-Event-Person-Event 等递归加载。因为这永远不会结束。如果您从一个人开始,并希望让所有人都与某个事件相关联,那么您会希望在另一个电话中获得这些人。
var person = db.GetWithChildren(1);
foreach(var event in person.Events)
{
// lazy load ourselves
var allParticipants = db.GetWithChildren(event.Id).Participants;
}
希望对您有所帮助
如果有人想查看有关使用 SQLite-Net Extensions 库创建多对多关系的更多详细信息,还包含@Shawn Kendrot 在此处提供的提示和解决方案,我已经收集了所有内容并且 wrote a post on my blog .
希望对您有所帮助:)
我在 Visual Studio 2015 年的 Xamarin.Android 项目中安装了 SQLite-Net Extensions 包,我正在尝试在 Person
和 Event
实体。我关注了 the official documentation of the library,但我无法让它正常工作。
类 我创建了:
Person.cs:
[Table("People")]
public class Person
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
[ManyToMany(typeof(PersonEvent), CascadeOperations = CascadeOperation.All)]
public List<Event> Events { get; set; }
}
Event.cs:
[Table("Events")]
public class Event
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
public DateTime Date { get; set; }
public string Place { get; set; }
[ManyToMany(typeof(PersonEvent), CascadeOperations = CascadeOperation.All)]
public List<Person> Participants { get; set; }
}
个人Event.cs:
public class PersonEvent
{
[ForeignKey(typeof(Person))]
public int PersonId { get; set; }
[ForeignKey(typeof(Event))]
public int EventId { get; set; }
}
为了测试它,我删除了数据库文件以确保在设备上创建了一个干净的文件,然后尝试创建一个 Person
、一个 Event
,将两者都插入到先DB,然后将Event
分配给Person
,然后使用UpdateWithChildren
方法再次保存:
var dbFile = new File(Constants.DbFilePath);
dbFile.Delete();
var db = new SQLiteConnection(new SQLitePlatformAndroid(), Constants.DbFilePath);
db.CreateTable<Person>();
db.CreateTable<Event>();
db.CreateTable<PersonEvent>();
var event1 = new Event
{
Name = "Volleyball",
Date = new DateTime(2017, 06, 18),
Place = "Sports hall"
};
var person1 = new Person
{
Name = "A",
LastName = "B",
PhoneNumber = "123456789"
};
db.Insert(person1);
db.Insert(event1);
person1.Events = new List<Event> { event1 };
db.UpdateWithChildren(person1);
首先,我需要添加 CreateTable<PersonEvent>()
行,因为如果它不存在,我会得到异常:SQLite.Net.SQLiteException: no such table: PersonEvent
,但我认为我不必创建这个中间table 手动。 SQLite-Net Extensions 不应该以某种方式自动创建它吗?
添加此行后,event1
和 person1
的前两个插入工作正常(插入后两个实体都分配了 ID)。 person1
上的 Events
集合甚至创建了 Event
,它也设置了 Id:
但是,"opposite entity",在本例中 event1
有其 Participants
集合(列表 Person
)NULL
:
我尝试了所有方法,但没有任何效果。据我了解阅读 SQLite-Net Extensions 文档,它应该自动解决。我什至在集合中添加了这个 CascadeOperations = CascadeOperation.All
,但如您所见,它没有帮助。我还是做错了什么?
The Events collection on person1 has even the Event created, which also has Id set
您的 person1
对象具有您创建的事件列表。该集合包含一个 link 到您创建的 event1
对象。当您插入或更新数据库时,此事件集合未更新。当您将 Event 对象插入数据库时,您会发现它设置了 Id,因为列表包含相同的对象。
SQLite-NET Extensions 不是 [自动] 延迟加载解决方案(如 Entity Framework)。它只有在被告知时才会获取对象。使用 Get 方法从数据库中获取对象与 SQLite 已经做的没有任何不同。这是因为 SQLite-NET Extensions 不会改变该方法。但是它确实提供了像 GetWithChildren and FindWithChildren 这样的新方法。如果你想获得一个对象的子对象,你需要 SQLite-NET Extensions 提供的方法。
提供的示例也使用了这些方法:
// Get the object and the relationships
var storedValuation = db.GetWithChildren<Valuation>(valuation.Id);
if (euro.Symbol.Equals(storedValuation.Stock.Symbol)) {
Debug.WriteLine("Object and relationships loaded correctly!");
}
您也不希望对象从 Person-Event-Person-Event 等递归加载。因为这永远不会结束。如果您从一个人开始,并希望让所有人都与某个事件相关联,那么您会希望在另一个电话中获得这些人。
var person = db.GetWithChildren(1);
foreach(var event in person.Events)
{
// lazy load ourselves
var allParticipants = db.GetWithChildren(event.Id).Participants;
}
希望对您有所帮助
如果有人想查看有关使用 SQLite-Net Extensions 库创建多对多关系的更多详细信息,还包含@Shawn Kendrot 在此处提供的提示和解决方案,我已经收集了所有内容并且 wrote a post on my blog .
希望对您有所帮助:)