0

I am attempting to structure my database appropriately for my web application. I am unsure the correct way to proceed with the keys and relationships. Basically..

My project contains a Product

Which can contain many Reports, however, the same Report can not relate to multiple Products.

I have Users, which may have many reports available to them.. regardless of the reports parent product.

My structure thus far

public class Product
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
}


public class Report
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual Product Product { get; set; }
}


public class User
{
    [Key]
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public virtual ICollection<Report> Reports { get; set; }
}


And to Seed

protected override void Seed(Insight.Data.InsightDb context)
    {
        context.Products.AddOrUpdate(p => p.ProductID,
            new Product { ProductName = "Product 1" },
            new Product { ProductName = "Product 2" }
        );

        context.Reports.AddOrUpdate(p => p.ReportID,
            new Report { ReportName = "Report A", ProductID = 1, },
            new Report { ReportName = "Report B", ProductID = 1, },
            new Report { ReportName = "Report C", ProductID = 1, },
            new Report { ReportName = "Report D", ProductID = 2, },
            new Report { ReportName = "Report E", ProductID = 2, }
        );

        context.Users.AddOrUpdate(u => u.UserID,
            new User { FirstName = "Frank", LastName = "Reynolds", },
            new User { FirstName = "Dee", LastName = "Reyonolds", }
        );
    }

I am unsure how to properly assign the Reports to the Users, or even know if I am on the right track. Also, is there a better practice than using int as a key?

2
  • 1
    Check out the edit I just made to your models. Maybe that will help a bit. If I'm understanding right.. you want a User who has a list of Reports associated with them, and you want a unique product in each of those reports? Commented Sep 17, 2013 at 19:15
  • Thank you. The entity models do correctly line up once I'm in SQL server and populate and query the tables manually. Can you offer an example to populate them appropriately within my C# code inside of Seed() ?
    – scniro
    Commented Sep 17, 2013 at 19:29

2 Answers 2

1

While I haven't used the approach you have above.. here's my stab at it:

protected override void Seed(Insight.Data.InsightDb context)
{
    var product1 = new Product{ Name = "Product 1"};
    var product2 = new Product{ Name = "Product 2"};
    var reports1 = new List<Report>
    {
        new Report { Name = "Report A", Product = product1, },
        new Report { Name = "Report B", Product = product1, },
        new Report { Name = "Report C", Product = product1, },
        new Report { Name = "Report D", Product = product2, },
        new Report { Name = "Report E", Product = product2, }
    };

    context.Products.AddOrUpdate(p => p.ProductID,
        product1,
        product2
    );

    context.Reports.AddOrUpdate(p => p.ReportID,
        reports1
    );

    context.Users.AddOrUpdate(u => u.UserID,
        new User { FirstName = "Frank", LastName = "Reynolds", Reports = reports1 },
        new User { FirstName = "Dee", LastName = "Reyonolds" },
    );
}

I'm just not sure if setting up the reports part is correct (adding a list to the AddOrUpdate function), so that's something you may have to look in to if this doesn't work.

6
  • Interesting. I see what is going on here. I tried, for example, to add 'report1' to Dee Reynolds as well (so they would have the same report) and receive an error: Collection was modified; enumeration operation may not execute. I took out the Reoirts.AddOrUpdate as well...
    – scniro
    Commented Sep 17, 2013 at 20:20
  • 1
    Can you do anything like context.Users.AddOrUpdate( ........ ).With( // This is where you would add the Reports) ? It's something like - stackoverflow.com/questions/11263542/… , but again, just not sure about the syntax. Commented Sep 17, 2013 at 20:26
  • You're looking for a one-to-many mapping, if that helps at all. Commented Sep 17, 2013 at 20:34
  • Thank you. Answer is sufficient for now. I'll have to refine it for my specific needs
    – scniro
    Commented Sep 17, 2013 at 20:36
  • PM me if you have any other specific questions. Sorry I wasn't able to help you completely. Commented Sep 17, 2013 at 21:46
0

I have found a solution. It turns out I was interested in a many-to-many relationship, with a bridge table in between Reports and Users. These are my entities to establish this relationship.

public class Report
{
    [Key]
    public int Id { get; set; }

    public string Name { get; set; }

    public virtual Product Product { get; set; }

    public virtual ICollection<User> Users { get; set; }
}

public class User
{
    [Key]
    public int Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public virtual ICollection<Report> Reports { get; set; }
}


Then to populate my data with a code first approach

protected override void Seed(Insight.Data.InsightDb context)
{
    Product product1 = new Product { Name = "Product 1" };
    Product product2 = new Product { Name = "Product 2" };

    Report reportA = new Report { Name = "Report A", Product = product1 };
    Report reportB = new Report { Name = "Report B", Product = product1 };
    Report reportC = new Report { Name = "Report C", Product = product1 };
    Report reportD = new Report { Name = "Report D", Product = product2 };
    Report reportE = new Report { Name = "Report E", Product = product2 };

    List<User> users = new List<User>();

    users.Add(new User { FirstName = "Dee", LastName = "Reynolds", Reports = new List<Report>() { reportA, reportB, reportC } });
    users.Add(new User { FirstName = "Frank", LastName = "Reynolds", Reports = new List<Report>() { reportC, reportD, reportE } });

    users.ForEach(b => context.Users.Add(b)); 
}

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.