孩子不会更新 Xamarin SQLite 扩展 - 多对多关系

Posted

技术标签:

【中文标题】孩子不会更新 Xamarin SQLite 扩展 - 多对多关系【英文标题】:Children won't updated Xamarin SQLite Extension - ManyToMany relationship 【发布时间】:2021-01-07 16:52:42 【问题描述】:

我有四个带属性的表(成员有球员,每个人都参加许多运动)最后一个表多对多关系的中间表

[Table("Members")]
public class MemberModel : BaseDatabaseItem

    public string MemberShipCode  get; set; 
    public string MemberShipYear  get; set; 

    [OneToMany(CascadeOperations = CascadeOperation.All)]
    public List<PlayerModel> MembershipNPlayers  get; set; 


[Table("Players")]
public class PlayerModel : BaseDatabaseItem

    public string PlayerName  get; set; 

    public double PlayerPayment  get; set; 

    [ForeignKey(typeof(MemberModel))]
    public int MemberModelId  get; set; 

    [ManyToMany(typeof(PlayerSport))]
    public List<Sport> Sports  get; set; 


[Table("Sports")]
public class Sport : BaseDatabaseItem

    private SportCaegory sportCaegory;

    public string SportName  get; set; 

    [Ignore]
    public SportCaegory SportCaegory 
    
        get 
        
            return sportCaegory = new SportCaegory
            
                SportPrice = SportPrice,
                SportType = SportType
            ;
        
        set
        
            sportCaegory = value;
            if (sportCaegory == null)
                return;
            SportType = sportCaegory.SportType;
            SportPrice = sportCaegory.SportPrice;
        
    

    public string SportType  get; set; 
    public double SportPrice  get; set; 

    [ManyToMany(typeof(PlayerSport))]
    public List<PlayerModel> Players  get; set; 



public class PlayerSport : BaseDatabaseItem

    [ForeignKey(typeof(PlayerModel))]
    public int PlayerModelId  get; set; 

    [ForeignKey(typeof(Sport))]
    public int SportId  get; set; 

BaseDataItem 只是一个有 ID 的类(Primary - AutoIn)

当我将会员保存在数据库中时,我会保存 Sports 然后 Players 最后是会员

            foreach (var sport in Players.SelectMany(p => p.Sports))
            
                await _sportsRepository.SaveItemAsync(new Sport
                
                    Id = sport.Id == 0 ? 0 : sport.Id,
                    SportName = sport.SportName,
                    SportCaegory = sport.SportCaegory
                );
            ;

            foreach (var player in Players)
            
                await _playersRepository.SaveItemAsync(new PlayerModel
                
                    Id = player.Id == 0 ? 0 : player.Id,
                    PlayerName = player.PlayerName,
                    PlayerPayment = player.PlayerPayment,
                    Sports = player.Sports
                );
                await _playersRepository.SaveWithChildrenAsync(player);

            ;

            var member = new MemberModel
            
                Id = string.IsNullOrEmpty(Id) ? 0 : int.Parse(Id),
                MemberShipCode = MemberShipCode,
                MemberShipYear = MemberShipYear,
                MembershipNPlayers = Players.ToList()
            ;

            await _membersRepository.SaveWithChildrenAsync(member);

SaveWithChildrenAsync(仅检查 Id)=>

    public async Task SaveWithChildrenAsync(T entity)
    
        if (entity.Id != 0)
            await UpdateWithChildren(entity);
        else
            await InsertWithChildren(entity);
    

当我检索数据时,每个球员的体育列表计数始终为零

        var member = await _membersRepository.GetWithChildren(MemberId) ;


        var MemberPlayers = member.MembershipNPlayers;

        foreach (var player in MemberPlayers)
        
            var p = await _playersRepository.GetWithChildren(player.Id);
            Players.Add(p);
        
        MemberShipCode = member.MemberShipCode;
        MemberShipYear = member.MemberShipYear;

如何解决?

【问题讨论】:

【参考方案1】:

由于您未提供某些部分代码,我编写了一个简单的代码来更新数据库并接收数据。你可以检查下面的代码。

模型类:

 [Table("Members")]
public class MemberModel : BaseDatabaseItem

    public string MemberShipCode  get; set; 
    public string MemberShipYear  get; set; 

    [OneToMany(CascadeOperations = CascadeOperation.All)]
    public List<PlayerModel> MembershipNPlayers  get; set; 


public class BaseDatabaseItem

    [PrimaryKey, AutoIncrement]
    public int Id  get; set; 


[Table("Players")]
public class PlayerModel : BaseDatabaseItem

    public string PlayerName  get; set; 

    public double PlayerPayment  get; set; 

    [ForeignKey(typeof(MemberModel))]
    public int MemberModelId  get; set; 

    [ManyToMany(typeof(PlayerSport))]
    public List<Sport> Sports  get; set; 


[Table("Sports")]
public class Sport : BaseDatabaseItem

    private SportCaegory sportCaegory;

    public string SportName  get; set; 

    [Ignore]
    public SportCaegory SportCaegory
    
        get
        
            return sportCaegory = new SportCaegory
            
                SportPrice = SportPrice,
                SportType = SportType
            ;
        
        set
        
            sportCaegory = value;
            if (sportCaegory == null)
                return;
            SportType = sportCaegory.SportType;
            SportPrice = sportCaegory.SportPrice;
        
    

    public string SportType  get; set; 
    public double SportPrice  get; set; 

    [ManyToMany(typeof(PlayerSport))]
    public List<PlayerModel> Players  get; set; 


public class SportCaegory

    public string SportType  get; set; 
    public double SportPrice  get; set; 



public class PlayerSport : BaseDatabaseItem

    [ForeignKey(typeof(PlayerModel))]
    public int PlayerModelId  get; set; 

    [ForeignKey(typeof(Sport))]
    public int SportId  get; set; 

插入和读取数据:

   var dbName = "CustomersDb.db3";
        var path = Path.Combine(System.Environment.
          GetFolderPath(System.Environment.
          SpecialFolder.Personal), dbName);


        var db = new SQLiteConnection(path);
        db.CreateTable<MemberModel>();
        db.CreateTable<PlayerModel>();
        db.CreateTable<PlayerSport>();
        db.CreateTable<Sport>();

        var Member1 = new MemberModel()
        

            MemberShipCode = "A",
            MemberShipYear = "111"
        ;
        var Player1 = new PlayerModel()
        
            MemberModelId = 12,
            PlayerName = "B",
            PlayerPayment = 1.2,

        ;
        var SportPlayer1 = new PlayerSport()
        
            PlayerModelId = 1,
            SportId = 2
        ;
        var Sport1 = new Sport()
        

            SportCaegory = new SportCaegory()
            
                SportPrice = 12,
                SportType = "tY"
            ,
            SportName = "Name1",
            SportPrice = 13,
            SportType = "ww"
        ;


        db.Insert(Member1);
        db.Insert(Player1);
        db.Insert(Sport1);
        db.Insert(SportPlayer1);

        Member1.MembershipNPlayers = new List<PlayerModel>  Player1 ;
        Player1.Sports = new List<Sport>  Sport1 ;
        Sport1.Players = new List<PlayerModel>()  Player1 ;

        db.UpdateWithChildren(Member1);
        db.UpdateWithChildren(Sport1);
        db.UpdateWithChildren(Player1);


        var M = db.GetWithChildren<MemberModel>(Member1.Id);
        var P = db.GetWithChildren<PlayerModel>(Player1.Id);

截图:

【讨论】:

SportPlayer1 中的 ids 是随机的,如果不是,将被覆盖你如何获得要插入的值? SportPlayer1 的 ID 继承自 BaseDatabaseItemBaseDatabaseItem 的 ID 是 PrimaryKey 和 AutoIncrement。对于插入数据库的每个新对象,它将导致整数属性的值自动递增。它不会被覆盖,而不是您插入存在的 ID。 不是主键而是子外键,但是感谢我没有将运动插入数据库,所以它总是为空

以上是关于孩子不会更新 Xamarin SQLite 扩展 - 多对多关系的主要内容,如果未能解决你的问题,请参考以下文章

当我尝试更新 sqlite 中的行时,Xamarin 中没有任何反应

Xamarin.Forms 中的 sqlite 如何更新本地数据库中的单个记录

如何在可扩展的listview android中将孩子添加到特定的父母

Xamarin.Forms NotifyPropertyChanged 不会更新现有项目 (Android)

将属性绑定到 Xamarin 中的 ListView,不会更新视图

小部件不会更新/重绘