1

I'm trying to create an many to many entity in asp.net C#. I have looked at the student/course example before and it is logical but something is literally wrong when I try use it in my own code.

Here is the code where I'm stuck.

    [HttpPost]
    public ActionResult BuyWeapon(int weaponId)
    {
        string currentUserId = User.Identity.GetUserId();

        var ctx = new DAL.ProjectStrawberryEntities();

        Character character = ctx.Characters.FirstOrDefault(c => c.AccountId == currentUserId);
        Weapon weapon = ctx.Weapons.FirstOrDefault(w => w.Id == weaponId);

        if (character.Gold - weapon.Price >= 0)
        {
            // Add weapon to character

            character.Gold -= (int)weapon.Price;
        }

        return View();
    }

The only properties Character and Weapon has is WeaponCharacter, which is my bridge table for Weapon and Character.

Here are my Character and Weapon models from my database.

public partial class Character
{
    public Character()
    {
        this.WeaponCharacters = new HashSet<WeaponCharacter>();
    }

    *Removed wall of propeties*

    public virtual AspNetUser AspNetUser { get; set; }
    public virtual Class Class { get; set; }
    public virtual Gender Gender { get; set; }
    public virtual ICollection<WeaponCharacter> WeaponCharacters { get; set; }
}

public partial class Weapon
{
    public Weapon()
    {
        this.WeaponCharacters = new HashSet<WeaponCharacter>();
    }

    *Removed wall of propeties*

    public virtual WeaponType WeaponType { get; set; }
    public virtual ICollection<WeaponCharacter> WeaponCharacters { get; set; }
}

public partial class WeaponCharacter
{
    public int CharacterId { get; set; }
    public int WeaponId { get; set; }
    public int Quantity { get; set; }

    public virtual Character Character { get; set; }
    public virtual Weapon Weapon { get; set; }
}

I cropped out some properties since they are unnecessary.
enter image description here

Shouldn't Character have an ICollection<Weapon>? Am I wrong to use a many to many relation for this?

The goal I'm trying to reach is: I want a character to buy a weapon, it is possible to buy several of the same weapon but only once per click.

tereško
  • 58,060
  • 25
  • 98
  • 150
Kokefa
  • 85
  • 9

1 Answers1

0

I might be wrong as I'm used to EntityFramework for Code-First aproach, but shouldn't your Character class have an ICollection<Weapon> property instead of 'WeaponCharacter'? On my experience (With EF, latest version) the ICollection would be automatically mapped to the WeaponCharacter table as you add items to that collection.

Example of a working many-to-many relationship, using EF-CodeFirst, where Prescricao has a many-to-many relationship with Remedio:

public class Prescricao
{
    // Hidden Properties

    /// <summary>
    /// Remédios prescritos para o paciente.
    /// </summary>
    public virtual ICollection<Remedio> Remedios { get; set; }

    public Prescricao()
    {
        Remedios = new List<Remedio>();
    }

}

public class Remedio
{
    /// <summary>
    /// Prescrições que incluem o remédio.
    /// </summary>
    public virtual ICollection<Prescricao> Prescricoes { get; set; }

    public Remedio()
    {
        Prescricoes = new List<Prescricao>();
    }

Adding something to the relationship:

var pres1 = new Classes.Prescricao()
        {
            DataEmissao = DateTime.Now,
            DataLimite = DateTime.Now.AddMonths(1),
            Descricao = "Prescrição teste.",
            Medico = m1,
            Paciente = p1,
            Status = Classes.PrescricaoStatus.Pendente
        };
var r1 = new Classes.Remedio()
        {
            NomeComercial = "Aspirina",
            PrecoMedio = 12.49m,
            PrincipioAtivo = "Whatever",
            Status = Classes.RemedioStatus.Aprovado
        };

        context.Remedios.Add(r1);
        pres1.Remedios.Add(r1);
        context.Prescricoes.Add(pres1);

(Was going to add this as a comment as I don't think this solves the issue at hand but I can't comment just yet)

Alves RC
  • 1,778
  • 14
  • 26
  • That's what I thought too, that `Character` should have an `ICollection`. I think something gone wrong when I added an extra column to the bridge table as I've done. I don't see how else I could solve this problem. – Kokefa Sep 16 '15 at 13:16
  • Is the field `Quantity` really required? What would caracterize the "same" weapon? If the weapon has the same attributes and a different ID, you could remove the `Quantity` field and use a Linq query to recover how many weapons of the same type a character has. Edit: Would this [question](http://stackoverflow.com/questions/15153390/many-to-many-mapping-with-extra-fields-in-fluent-api) help you? Seems like the guy also had an issue with an extra-field in a Many-To-Many relationship. – Alves RC Sep 16 '15 at 13:25
  • To be honest, I'm not sure if I'm thinking correctly to use a many to many in this situation. The field `Quantity` is as it says, "User 1 has 2 Quanities of Weapon 1". I dont think it's possible to have two identical entries in a many to many? like "User1, Weapon1" twice? That question, was he using code first? I'm going database first. – Kokefa Sep 16 '15 at 13:40
  • Oh, true, he was using a Code-First aproach. And I don't think it would be possible as it might hurt the Primary Key constraint on the relationship table. How about adding a `Quantity` property to the `Weapon` class? That way you can move it away from the `WeaponCharacter` table and you would still be able to quantify the ammount of weapons a character has! – Alves RC Sep 16 '15 at 13:47
  • I will give that a try later! – Kokefa Sep 16 '15 at 13:55