LINQ with Entity Framework - basic question - c#

I am trying to learn linq to sql/objects as quick as possible. I have a database with a Category table, and a sub_category table. A Category can have many Sub Categories. As a lesson, I am getting a list of categories. User enters the primary key from a displayed category, and then I wnt to display all sub categories.
Displaying the categories was easy... But Entity Framework has removed the foreign keys from Sub Category! I expect to see a category Id in the sub category table (As there is in the SQL server database model).
Instead, I have some CategoryReference property... How do I manage this?
static void Main(string[] args)
{
BudgieMoneyEntities db = new BudgieMoneyEntities();
var categories = (
from category in db.categories
select category).ToList();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Categories:");
Console.ForegroundColor = ConsoleColor.White;
foreach (category cat in categories)
{
Console.WriteLine(string.Format("{0:00} {1}", cat.category_id,
cat.description));
}
int categoryId = WaitForKey();
var subcategories = (
from subcategory in db.sub_category
where subcategory ?? ?
select subcategory).ToList();
}
The ?? is where I have got stuck... How do I do this where clause?

Try this:
var subcategories = (
from subcategory in db.sub_category
where subcategory.category.category_id == categoryId
select subcategory).ToList();
The names of the properties category and category_id can be different. You can look at your model in the EF designer what the actual names are. If the category property is missing, make sure you've got a foreign key relationship between the categories table and the subcategories table.
You also want to change the default names of entities and properies in the EF designer. For instance, use plural names for sub collections. For instance, use db.SubCategories instead of db.sub_category. That makes it much more readable.

Related

Create a table in SQL Server where the name is a variable in C#?

Using Visual Studio and SSMS.
I have a form where a user registers a username and it's stored like this:
List<SqlParameter> sqlNewTable = new List<SqlParameter>();
sqlNewTable.Add(new SqlParameter("Username", txtUser.Text));
DAL.ExecSP("CreateUserCourses", sqlNewTable);
From there, can I create a stored procedure called CreateUserCourses in which it creates a new table where the users input (their username) is the name of a new table?
Sure you can, but why?
Supposing you have a User table and a Course table. Then just make a 3rd table which maps those tables together Called UserCourses. This is called a Many-to-Many (mapping table) and it will containing an ID of both the User, and Course and any other relevant information .
This will make your life a lot easier going forward
Many-to-many (data model)
A many-to-many relationship is a type of cardinality that refers to
the relationship between two entities1 A and B in which A may
contain a parent instance for which there are many children in B and
vice versa.
For example, think of A as Authors, and B as Books. An Author can
write several Books, and a Book can be written by several Authors
Example
student: student_id, first_name, last_name
classes: class_id, name, teacher_id
student_classes: class_id, student_id // mapping table
SQL queries could look like this
Getting all students for a class
SELECT s.student_id, last_name
FROM student_classes sc
INNER JOIN students s ON s.student_id = sc.student_id
WHERE sc.class_id = X
Getting all classes for a student
SELECT c.class_id, name
FROM student_classes sc
INNER JOIN classes c ON c.class_id = sc.class_id
WHERE sc.student_id = Y
Entity framework queries could look like this
Getting all students for a class
var students = db.Students.Where(x => x.StudentClasses
.Any(y => y.ClassId == 1);
Getting all classes for a student
var classes = db.classes.Where(x => x.StudentClasses
.Any(y => y.StudentId == 1);

Adding multiple Products into same Order table. (M-M relationship)

Doing a shop project. Upon checkout, I create a list of all added product from cart and put it inside Order.Products(M-M relationship):
List<Product> productList = Cart.Select(item => db.Products.SingleOrDefault(x => x.Id == item)).ToList();
var addOrder = new Order
{
Id = Guid.NewGuid(),
UserId = userId,
OrderDate = DateTime.Now,
Products = productList
};
db.Orders.Add(addOrder);
db.SaveChanges();
I debugged my code to make sure the productsList had the right amount.
But after I added it, I only had one of each added products were added in my db. For e.g. if I have 3x cars, 4x books and 2x boat, then I just get one of each into M-M table, meaning total 3 products, even though I had total 9 in productList.
This is how I set up my m-m relationship.
create table Product_Order (
ProductId uniqueidentifier foreign key references [Product](ID) not null,
OrderId uniqueidentifier foreign key references [Order](Id) not null
)
Btw, is it possible to add additional column into Product_Order so called AmountProduct, and set amount value instead making many rows of same products/order? If possible, how do I set amount value inside var addOrder = new Order{? That way would probably be much more effective.

Including a second query in Entity Framework LINQ Query

I've got a table "Houses" and "Cats", which contains the columns "Id" and "HouseName" and "Id" and "CatName".
Now I got a table "HouseCatAssignments", where I store the relations between the Cats and the Houses (the Cat can live in more than one house and one house can store more than one cat).
This table looks like:
Id, CatId, HouseId
"CatId" is bound to Cats.Id and HouseId is bound to Houses.Id.
Now I want to display the Table "House" in a datagrid that also contains a field for "CatCount" - a counter for the value of how many cats are living in this house.
How should I now query my tables so I have all the values of "Houses" and an additional Column that contains the Cat-Count for the specific house?
For Entity Framework it should have automatically added navigation properties that allow you to do the following query:
var housesWithCount = context.Houses
.Select( h=> new
{
Id = h.Id,
HouseName = h.HouseName,
CatCount = h.Cats.Count()
});

C# - Entity Framework inserting

I have two tables Category and Product and I would like to insert products into categories. The table relation between these tables is one to zeor or one.
Category table:
CID : integer,
CategoryName : varchar,
Product table:
CID: integer, // foreign key to category table.
ProductName: varchar,
UnitsInstock: integer,
How can I write a simple query for inserting a product into the ProductTable? How do I handle the foriegn key situation? If the categoryid does not exists then the product should not be inserted.
I would realy appreciate any kinds of help.
One approach could be this one:
int categoryIdOfNewProduct = 123;
using (var context = new MyContext())
{
bool categoryExists = context.Categories
.Any(c => c.Id == categoryIdOfNewProduct);
if (categoryExists)
{
var newProduct = new Product
{
Name = "New Product",
CategoryId = categoryIdOfNewProduct,
// other properties
};
context.Products.Add(newProduct); // EF 4.1
context.SaveChanges();
}
else
{
//Perhaps some message to user that category doesn't exist? Or Log entry?
}
}
It assumes that you have a foreign key property CategoryId on your Product entity. If you don't have one please specify more details.
Normally a category to product would be many to one, but I would suggest studying the basics of Linq to Sql first:
http://msdn.microsoft.com/en-us/library/bb425822.aspx
Linq to Sql 101
Learn the Entity Framework

How can I model this class in a database?

I need a little of help. This is my design to organize several categories.
Category 1
Sub Category 1.1
Sub Category 1.1.1
Sub Category 1.2
Sub Category 1.3
It would be a collection. I want to store it in a database, but I don't know how can I model it in a database table. I'm using SQL Server CE.
UPDATE:
I forgot put the objective number in the class (1.1, 1.1.1).
You'd have a table something like this:
category
id (primary key, not null)
name (text, not null)
parent_category_id (foreign key to category.id, nullable)
Then, if a category has a parent, you reference the id of that other row. So the table is self-referential. Toplevel categories have a null parent_category_id.
When building tables like this you do need to be careful that you don't create a circular reference.
I'd use a simple Recursive Relation. Each Category should have a unique ID (primary key) and an optional field specifying its parent, which would be a foreign key mapping back to the same table. Categories with a NULL parent are top-level categories.
The page I linked to also has information on how you can query this structure to find top-level or mid-level Categories.
For this, you can have a table where an item can reference its parent, if any.
If the ParentId column is NULL, the category is a root one. If not, the parent is referenced.
You can then find the subcategories of a category by walking through the table and searching for items with ParentId equal to Id of the category.
Note that ParentId must be indexed for better performance, and that there must be a foreign key of ParentId to Id to ensure the validity of your data.
Storing recursively the categories:
private void SaveCategoryRecursively(Category category)
{
foreach (var subCategory in category.SubCategories)
{
query(#"
insert into [dbo].[Categories] ([Id], [ParentId], ...)
values (#id, #parentId, ...)", ...);
this.SaveCategoryRecursively(subCategory);
}
}
public void SaveCategories(IEnumerable<Category> rootCategories)
{
foreach (var category in rootCategories)
{
query(#"
insert into [dbo].[Categories] ([Id], [ParentId], ...)
values (#id, NULL, ...)", ...);
this.SaveCategoryRecursively(category);
}
}
Here is my recommendation. Create Three tables. I am assuming that each table has different columns
Category { Id, Name,...}
SubCategory {Id, Name, ..., **ParentID**} [ParentID is a FK from Category table Id Column]
SubSubCategory {Id, Name, ..., **SubParentID**} [SubParentID is a FK from SubCategory table ParentID Column]

Categories