- edited description
ManyToOne relation not working, throwing NullReferenceExc.
The table layout is as following:
public class Artist
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
[OneToMany]
public List<Track> Tracks { get; set; }
}
public class Track
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Title { get; set; }
public string Path { get; set; }
public string Filename { get; set; }
[ManyToOne]
public Artist Artist { get; set; }
[ForeignKey(typeof(Artist))]
public int ArtistId { get; set; }
}
I can create artists without a problem (not linking any tracks). Creating a track linked to an artist gives a NullReferenceException thrown in TableQuery.cs:407
if (mem.Expression != null && mem.Expression.NodeType == ExpressionType.Parameter)
{
//
// This is a column of our table, output just the column name
// Need to translate it if that column name is mapped
//
string columnName = Table.FindColumnWithPropertyName(mem.Member.Name).Name;
return new CompileResult
{
CommandText = "\"" + columnName + "\""
};
}
This is because we are trying to find a column named Artist, instead of the relation itself.
I don't really know enough about this library to see where (and why) it goes wrong.
If you need more info, please ask.
Edit:
When removing the ArtistId column and letting the ORM create its own mapping, I get the following create table query:
"create table if not exists \"Track\"(\n\"Id\" integer primary key autoincrement not null ,\n\"Title\" varchar(140) ,\n\"Path\" varchar(140) ,\n\"Filename\" varchar(140) )"
Where I don't see any reference to the Artist table.
Edit number 2:
The class responsible for managing data access (sorta)
public MusicTrackerDataContext()
{
connection = new SQLiteConnection(new SQLitePlatformWinRT(), Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, DATABASE_NAME));
Initialize();
ArtistTable = connection.Table<Artist>();
TrackTable = connection.Table<Track>();
}
private void Initialize()
{
var result = connection.CreateTable<Artist>();
result = connection.CreateTable<Track>();
}
That class is called whenever a connection to the database is made.
Then the class where we use the database (scanning a library and adding entities)
private Track CreateTrack(string trackTitle, Artist artist)
{
var track = dbContext.TrackTable.Where(
t =>
t.Title == trackTitle && t.Artist == artist
).FirstOrDefault();
if (track == null)
{
track = new Track();
track.Title = trackTitle;
dbContext.Insert(track);
track.Artist = artist;
dbContext.InsertWithChildren(track);
}
return track;
}
private Artist CreateArtist(string artistName)
{
var artist = dbContext.ArtistTable.Where(
a => a.Name == artistName
).FirstOrDefault();
if (artist == null)
{
artist = new Artist();
artist.Name = artistName;
dbContext.Insert(artist);
}
return artist;
}
The code fails when we try the Where(), because the column Artist does not exist.
It is circumvented by the following code
var track = dbContext.TrackTable.Where(
t =>
t.Title == trackTitle && t.ArtistId == artist.Id
).FirstOrDefault();
It works, but it's not how I want to interact with my data. Using it like this means that wherever I want to look for something, I need to remember to use ids, and not entities. (the same applies for adding, updating and retrieving entities with a OneToMany relation, I need to {Insert,Update,Get}WithChildren()).
Comments (7)
-
reporter -
The NullReferenceException is not being raised in SQLite-Net Extensions code, but in SQLite-Net code.
ManyToOne
(and all relationship attributes) inherit fromIgnoreAttribute
, so SQLite-Net should ignore that properties when inserting/reading the objects into/from the database.Maybe you are missing the call to
conn.CreateTable<Artist>
? If you can provide a sample project I'll try to help you further. -
reporter - edited description
-
I see, the problem is that you are accessing a SQLite-net Extension relationship property in a SQLite-Net query. Joining tables in queries is not currently supported in SQLite-Net Extensions, and won't be supported in a near future.
-
reporter That's too bad. Do you know what would be needed to support this? If I have some time I might take a look (but I'm fairly new to RT and LINQ)
-
You could start taking a look at how the
Where
statement is implemented in SQLite.Net -
- changed status to wontfix
Closed. This functionality won't be implemented by now.
- Log in to comment