Heron
Heron

Reputation: 33

Foreign key relation on WebAPI class

--- Solution ---

Thanks all for helping me, I was doing 1 thing wrong, I had 2 contexts because I didn't understand the concept, but now I've fixed it.

Here's what I changed based on your comments for it to work:

public class DatabaseContext : DbContext
{
    public DatabaseContext(DbContextOptions<DatabaseContext> options)
        : base(options)
    {
    }

    public DbSet<Grupo> Grupos { get; set; }
    public DbSet<Produto> Produtos { get; set; }

}

public class ProdutoRepository : IDefaultRepository<Produto>
{
    private readonly DatabaseContext _context;

    public ProdutoRepository(DatabaseContext context)
    {
        _context = context;

        if (_context.Produtos.Count() == 0)
            Add(new Produto { Nome = "Teste", GrupoId = 1 });
    }

    public IEnumerable<Produto> GetAll()
    {
        return _context.Produtos.Include(p => p.Grupo).ToList();
    }

    public void Add(Produto item)
    {
        _context.Produtos.Add(item);
        _context.SaveChanges();
    }

    public Produto Find(long key)
    {
        return _context.Produtos.Include("Grupo").FirstOrDefault(t => t.Id == key);
    }

    public void Remove(long key)
    {
        var entity = _context.Produtos.First(t => t.Id == key);
        _context.Produtos.Remove(entity);
        _context.SaveChanges();
    }

    public void Update(Produto item)
    {
        _context.Produtos.Update(item);
        _context.SaveChanges();
    }
}

public class GrupoRepository : IDefaultRepository<Grupo>
{
    private readonly DatabaseContext _context;

    public GrupoRepository(DatabaseContext context)
    {
        _context = context;

        if (_context.Grupos.Count() == 0)
            Add(new Grupo { Nome = "Teste" });
    }

    public IEnumerable<Grupo> GetAll()
    {
        return _context.Grupos.ToList();
    }

    public void Add(Grupo item)
    {
        _context.Grupos.Add(item);
        _context.SaveChanges();
    }

    public Grupo Find(long key)
    {
        return _context.Grupos.FirstOrDefault(t => t.Id == key);
    }

    public void Remove(long key)
    {
        var entity = _context.Grupos.First(t => t.Id == key);
        _context.Grupos.Remove(entity);
        _context.SaveChanges();
    }

    public void Update(Grupo item)
    {
        _context.Grupos.Update(item);
        _context.SaveChanges();
    }
}

--- /Solution ---

--- EDIT #4 ---

I don't know if I should point that I want it to be automatic, if I put a FK, I want to point it to the object so it will bring it on the JSON without making it manually.

--- /EDIT #4 ---

--- EDIT #3 ---

Okay, so I couldn't solve it, so I put the code on GitHub so you could take a look, is just a test project so no problem, is a small project.

https://github.com/heronz/LysiSolutionNumber01

--- /EDIT #3 ---

I'm new to C# and WebAPI development and I'm trying to learn how to make the relationship of 2 objects using a foreign key and when to access the endpoint I'd like it to bring something like this:

{
    productId:1,
    productName:"Test",
    productGroupId:1
    productGroup:{
        groupId:1,
        groupName:"Test Group"
    }
}

But I'm getting something like this:

{
    productId:1,
    productName:"Test",
    productGroupId:1
    productGroup:null
}

In my classes, I'm already using the annotations like this

public class Product
{        
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long productId{ get; set; }
    public string productName{ get; set; }

    [ForeignKey("group")]
    public long productGroupId{ get; set; }        
    public virtual Group productGroup{ get; set; }
}

public class Group
{        
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long groupId{ get; set; }
    public string groupName{ get; set; }
}

And I'm using the repository/context as taught in this tutorial

https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api

When I initiate my repository I use it like this:

public ProductRepository(ProductContext context)
{
    _context = context;

    if (_context.Reg.Count() == 0)
        Add(new Product{ productName = "Test", productGroupId= 1 });
}

I've tried searching how should I do it, found something about DTO but I didn't understand, so maybe there's that.

I'm in the process of learning, so there's no ready application only something I build based on the tutorial that I mentioned above.

--- EDIT ---

As asked on the comments, here is the GET method.

public IEnumerable<Product> GetAll()
{
    return _context.Reg.ToList();
}

public Produto Find(long key)
{
    return _context.Reg.FirstOrDefault(t => t.Codigo == key);
}

This is the context (edited):

public class ProductContext : DbContext
{
    public ProductContext(DbContextOptions<ProductContext> options)
        : base(options)
    {
    }

    public DbSet<Product> Reg { get; set; }

}

--- EDIT #2 ---

Tried adding a products reference on group

public class Group
{        
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long groupId{ get; set; }
    public string groupName{ get; set; }
    public virtual ICollection<Product> Products{ get; set; }
} 

And on the GET methods added the included thing

public IEnumerable<Product> GetAll()
{
    return _context.Reg.Include(p => p.productGroup).ToList();
}

public Produto Find(long key)
{
    return _context.Reg.Include(p => p.productGroup).FirstOrDefault(t => t.Codigo == key);
}

Still not working, maybe there's something with the way I reference the group in here?

public ProductRepository(ProductContext context)
{
    _context = context;

    if (_context.Reg.Count() == 0)
        Add(new Product{ productName = "Test", productGroupId= 1 });
}

Because, this way I'm only referencing the FK, maybe I need to reference the object? But how?

Upvotes: 3

Views: 1900

Answers (1)

Tiago S
Tiago S

Reputation: 1326

You will need to make some changes:


ProductContext

Add the following line

public DbSet<Group> Group { get; set; }

Classe Product

Delete the following property

public long productGroupId { get; set; }

The system already recognizes FK and creates the field at the base.


Class where you insert the new product

Here, you will get the group from database (assuming the group is already registered)

var group = _context.Group.Find(1);

Create a new product collection if it is null.

if (group.Products == null)
    group.Products = new List<Product>();

And then you add to the list of products for the selected group.

 group.Products.Add(new Product { productName = "Test" });

Staying like this:

public ProductRepository(ProductContext context)
{
    _context = context;
    var group = _context.Group.Find(1);

    if (group.Products == null)
        group.Products = new List<Product>();

    if (_context.Reg.Count() == 0)
       group.Products.Add(new Product { productName = "Test" });
}

Upvotes: 1

Related Questions