how to access items from one model inside another when I save the items in xamarin forms

103 Views Asked by At

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

1

There are 1 best solutions below

2
Jessie Zhang -MSFT On BEST ANSWER

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
}