问题
I have really been searching around for a while now but cannot find and understand how this do work. I am going to create an app in Xamarin forms and starting with SQLite. I need to have unique list items for each Main item in the app.
For example, I am having a list with items. When I am selecting an item in the list a new page will pop up and display the items of that item.
So from my point of view I am in need of two SQLite tables with relations between.
This is the Main table with all profiles
[Table("Profiles")]
public class ProfileItems
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string ProfileName { get; set; }
public string ProfileRace { get; set; }
public string iconn = "icon.png";
public string ProfileIcon { get; set; }
public DateTime BDay { get; set; }
[OneToMany(CascadeOperations = CascadeOperation.All)]
public List<LoggItems> Loggs { get; set; }
}
This is the logg table for each Profile, which should be unique for each profile
[Table("Loggs")]
public class LoggItems
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Title { get; set; }
public string Text { get; set; }
[ForeignKey(typeof(ProfileItems))]
public int ProfileId { get; set; }
}
Adding the items like this
public class ProfileDatabase
{
readonly SQLiteAsyncConnection database;
public ProfileDatabase(string dbPath)
{
database = new SQLiteAsyncConnection(dbPath);
database.CreateTableAsync<ProfileItems>().Wait();
database.CreateTableAsync<LoggItems>().Wait();
}
//Profile
public Task<List<ProfileItems>> GetProfileAsync()
{
return database.Table<ProfileItems>().ToListAsync();
}
public Task<ProfileItems> GetProfileAsync(int id)
{
return database.Table<ProfileItems>().Where(i => i.Id == id).FirstOrDefaultAsync();
}
public Task<int> SaveProfileAsync(ProfileItems profileItems)
{
if (profileItems.Id != 0)
{
return database.UpdateAsync(profileItems);
}
else
{
return database.InsertAsync(profileItems);
}
}
public Task<int> DeleteProfileAsync(ProfileItems profileItems)
{
return database.DeleteAsync(profileItems);
}
//Logg
public Task<List<LoggItems>> GetLoggAsync()
{
return database.Table<LoggItems>().ToListAsync();
}
public Task<LoggItems> GetLoggAsync(int id)
{
return database.Table<LoggItems>().Where(i => i.Id == id).FirstOrDefaultAsync();
}
public Task<int> SaveLoggAsync(LoggItems loggItems)
{
if (loggItems.Id != 0)
{
return database.UpdateAsync(loggItems);
}
else
{
return database.InsertAsync(loggItems);
}
}
public Task<int> DeleteLoggAsync(LoggItems loggItems)
{
return database.DeleteAsync(loggItems);
}
}
Both Logg and Profile list/tables do work but they do not have any relations between so the loggs show the same in all profile.
Please help me how I should do this.
Thanks in advanced.
回答1:
How about to use Linq and join the relationships.
1.- First you have to add the namespace:
using System.Linq;
2.- Change the property in the class ProfileItems to be a IEnumerable
[OneToMany(CascadeOperations = CascadeOperation.All)]
public virtual IEnumerable<LoggItems> Loggs { get; set; }
3.- This is the method to join the loggs with the profile items.
var profiles = await GetProfileAsync();
var loggs = await GetLoggAsync();
var query = from p in profiles
join l in loggs on p.Id equals l.ProfileId into list
select new ProfileItems
{
Id = p.Id,
ProfileIcon = p.ProfileIcon,
ProfileName = p.ProfileName,
ProfileRace = p.ProfileRace,
BDay = p.BDay,
Loggs = list
};
回答2:
I think you must add "virtual" keyword for enabling lazy loading.
[OneToMany(CascadeOperations = CascadeOperation.All)]
public virtual List<LoggItems> Loggs { get; set; }
And there's the "[InverseProperty]" to specify their related navigation property.
public class LoggItems
{
*
[ForeignKey(typeof(ProfileItems))]
[InverseProperty("Loggs")]
public int ProfileId { get; set; }
*
}
来源:https://stackoverflow.com/questions/50802032/xamarin-forms-sqlite-relation