0

I want to get data from multiple tables based on the itemId of each table.

Currently I have an item table with an ItemId column that has a 1:m relationship with another tables called ExplicitMods:

namespace Poe.Models
{
    public class Item
    {
        [Key]
        public string ItemId { get; set; }
        public List<ExplicitMod> ExplicitMods { get; set; }
    }
}

namespace Poe.Models
{
    public class ExplicitMod       
    {
        public ExplicitMod(string Name)
        {
            this.Name = Name;
        }

        [Key]
        public string ItemId { get; set; } 
        public string Name { get; set; }
    }
}

I also have a context with both tables set up:

namespace Poe.DataAccess
{
    public class DatabaseContext : DbContext
    {
        public DbSet<Item> Items { get; set; }
        public DbSet<ExplicitMod> ExplicitMod { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
        }
    }
}

I then try to call the item tables, search on a random name called "Brood Star", and join the explicitMod table:

public static void Search()
{
    //return FindItems(i);
    using (var db = new DatabaseContext())
    {
        var blogs = db.Items
                    .Where(b => b.Name.Equals("Brood Star"))
                    .Include(es => es.ExplicitMods).ToList();
        Debug.Write(blogs);
    }
}

What should I do to get the result as one table?

I also get this error:

System.Data.SqlClient.SqlException: 'Invalid object name 'ExplicitMod'

1
  • I think Include() has to go before Where(). Is this EF Core? Commented Nov 20, 2018 at 21:28

1 Answer 1

1

Your references need a bit of adjustment. For a 1-many, your ExplicitMod will need it's own PK, and a FK to Item:

public class ExplicitMod       
{
    public ExplicitMod()
    {}

    public ExplicitMod(string name)
    {
        Name = name;
    }

    [Key]
    public string ExplicitModId { get; set; } 
    [ForeignKey("Item")]
    public string ItemId{ get; set; }
    public string Name { get; set; }
    public virtual Item Item { get; set; }
}

I believe it also will need a parameterless constructor for EF to be able to construct these on the fly. You may be able to get away with a protected or private constructor.

For Item:

public class Item
{
   [Key]
    public string ItemId { get; set; }
    public virtual ICollection<ExplicitMod> ExplicitMods { get; private set; } = new List<ExplicitMod>();
}

Initializing the collection and using a private setter is recommended to save steps when creating new entities to populate, and having external code setting a collection reference to a new, untracked set of entities. (For unit testing, I typically mark the setter internal to allow unit tests to set up stubs)

I'd strongly recommend using an int or Guid for the PK/FK fields rather than strings. If you want to have unique identifying strings then add these as additional columns /w unique constraints. Using numeric or UUID keys are a form of "meaningless keys" which save indexing space and make modifying values easier without worrying about changing/invalidating data relationships accidentally.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.