I am creating a project using sqlite in xamarin forms, I am experiencing a problem that, on the save new items page, I create an instance of my ITEM model and within the ITEM I reference another model which is PRIORITY, when I click on save items and I leave it in debug mode, I can receive all the items, including the saved PRIORITY, but within the variable where I add the items in SQLite it returns the PRIORITY as follows: ItemPriority = {CrudTasks.Models.Priority}
And when I try to access these items on the View Page I get no response.
//Function SaveItems
private async void ExecuteSaveItemsCommand()
{
try
{
Item itemSaved = new Item
{
Name = NameSave,
Description = DescriptionSave,
ItemPriority = new Priority()
{
PriorityName = PrioritySave,
PriorityColor = "#ccc"
}
};
_itemsService.InsertItem(itemSaved);
ExecuteBackProductPageCommand();
}
catch (Exception ex)
{
await Shell.Current.DisplayAlert("Error", ex.Message, "OK");
}
}
//Model Item
namespace CrudTarefas.Models
{
[Table("Items")]
public class Item
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
[ManyToOne]
public Priority ItemPriority { get; set; }
}
}
//Model Priority
namespace CrudTarefas.Models
{
[Table("Priorities")]
public class Priority
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string PriorityName { get; set; }
public string PriorityColor { get; set; }
}
}
//CollectionView ListItemsPage
<ScrollView VerticalScrollBarVisibility="Never">
<StackLayout>
<CollectionView ItemsSource="{Binding ItemsList}">
<CollectionView.ItemsLayout>
<LinearItemsLayout ItemSpacing="20" Orientation="Vertical" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Grid
Margin="0,0,0,20"
Padding="10"
xct:CornerRadiusEffect.CornerRadius="12"
BackgroundColor="{Binding ItemPriority.PriorityColor}"
RowDefinitions="*,20,20"
RowSpacing="10">
<Frame
Grid.Row="0"
Padding="5"
HorizontalOptions="Start">
<Label Text="{Binding ItemPriority.PriorityName}" />
</Frame>
<Label
Grid.Row="1"
Text="{Binding Name}"
TextColor="Black" />
<Label
Grid.Row="2"
Text="{Binding Description}"
TextColor="Black" />
</Grid>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ScrollView>
//Viewmodel ListItems
-> In the LOADITEMS method in the commented code, I can access the static item with the collectionView
#region constructor
public ListItemsViewmodel(INavigation navigation)
{
Navigation = navigation;
_itemsService = new ItemsService();
LoadItems();
GoAddItemPageCommand = new Command(ExecuteGoAddItemPageCommand);
LoadItemsCommand = new Command(ExecuteLoadItemsCommand);
}
#endregion
#region commands
public ICommand GoAddItemPageCommand { get; set; }
public ICommand LoadItemsCommand { get; set; }
#endregion
#region methods
-> private void LoadItems()
{
var items = _itemsService.GetAllItems();
ItemsList = new ObservableCollection<Item>(items);
}
I can't access another model's table
Based on your code, I created a demo and achieved this function on my side.
You can try to modify your code as follows:
1.add a foreign Key ( public int ItemId { get; set; }
) for Priority.cs
[Table("Priorities")]
public class Priority
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string PriorityName { get; set; }
public string PriorityColor { get; set; }
[ForeignKey(typeof(Item))]
public int ItemId { get; set; }
}
2.change [ManyToOne]
to OneToOne
for Item.cs
[Table("Items")]
public class Item
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
//add attribute OneToOne
[OneToOne]
public Priority ItemPriority { get; set; }
}
3.add several methods(InsertPriority
and UpdatePriority
) for IItemsService.cs
public interface IItemsService
{
List<Item> GetAllItems();
void InsertItem(Item item);
//add method InsertPriority
void InsertPriority(Priority item);
//add method UpdatePriority
void UpdatePriority(Priority item);
void UpdateItem(Item item);
void DeleteItem(int id);
bool ExistsItem(string name, string description, string priorityName);
}
4.implement above interface InsertPriority
and UpdatePriority
for class ItemsService.cs
.
And we also need to replace code var items = _connection.Table<Item>().ToList();
with code var items = _connection.GetAllWithChildren<Item>();
on method GetAllItems()
public class ItemsService : IItemsService
{
private SQLiteConnection _connection;
public ItemsService()
{
SetupDb();
}
private void SetupDb()
{
if(_connection == null)
{
string dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "ItemsDb.db3");
_connection = new SQLiteConnection(dbPath);
_connection.CreateTable<Item>();
_connection.CreateTable<Priority>();
}
}
public void InsertItem(Item item)
{
_connection.Insert(item);
}
public void UpdateItem(Item item)
{
// _connection.Update(item);
// replace above code with the following code
_connection.UpdateWithChildren(item);
}
public void DeleteItem(int id)
{
_connection.Delete(id);
}
public List<Item> GetAllItems()
{
//var items = _connection.Table<Item>().ToList();
// replace above code with the following code
var items = _connection.GetAllWithChildren<Item>();
return items;
}
public bool ExistsItem(string name, string description, string priorityName)
{
var existsItem = _connection.Table<Item>().FirstOrDefault(it => it.Name == name && it.Description == description
&& it.ItemPriority.PriorityName == priorityName);
return existsItem != null;
}
public void InsertPriority(Priority item)
{
_connection.Insert(item);
}
public void UpdatePriority(Priority item)
{
_connection.Update(item);
}
}
5.modify command ExecuteSaveItemsCommand
for AddItemViewmodel.cs
public class AddItemViewmodel : BaseViewmodel
{
//For the sake of simplicity, omit the other codes
#region methods
//Function SaveItems
private async void ExecuteSaveItemsCommand()
{
try
{
Item itemSaved = new Item()
{
Name = NameSave,
Description = DescriptionSave,
//ItemPriority = new Priority
//{
// PriorityName = PrioritySave,
// PriorityColor = "#ccc"
//}
};
// _itemsService.InsertItem(itemSaved);
Priority ItemPriority = new Priority
{
PriorityName = PrioritySave,
PriorityColor = "#ccc"
};
_itemsService.InsertItem(itemSaved);
_itemsService.InsertPriority(ItemPriority);
itemSaved.ItemPriority = ItemPriority;
_itemsService.UpdateItem(itemSaved);
_itemsService.UpdatePriority(ItemPriority);
ExecuteBackProductPageCommand();
}
catch (Exception ex)
{
await Shell.Current.DisplayAlert("Error", ex.Message, "OK");
}
}
private async void ExecuteBackProductPageCommand()
{
await Navigation.PopAsync();
}
#endregion
}