I have 2 tables Center (centerId, name, address,...) and Student (StudentId, NAme, Address) and I determined they have a many-to-many relationship. As a result, I have created a new table CenterStudent (centerId, studentId,...) to join these 2 tables, and I set both centerId, studentId is PK and FK, and cascade delete.
Now I want to get all records with the same studentId. So I wrote
var lists = await studentCenterService.GetAsync(cancellationToken, studentId);
But I get an error
Entity type 'UserCenter' is defined with a 2-part composite key, but 1 values were passed to the 'DbSet.Find' method.
Could anyone give me a solution?
The error seems pretty clear - the .Find() method in EF works only on the complete PK - so if you have a PK made up from two columns (centerId, studentId), you cannot use .Find() to find all entries if you only supply studentId.
You need to use a
UserCenter.Where(x => x.studentId == studentId)
approach instead.
Related
I am using C# to select data from my database. Now i have two table, the first one is aspnetuser, the second one is aspnetuserroles, the aspnetuserroles have the foreign key linkage with aspnetuser table, when i perform the following query
db.AspNetUsers.ToList()
the aspnetroles data will appeared in the aspnetusers data. This will cause my datatable unable to display its data because datatable expect one value in one column parameter. If the aspnet roles data inside that json, it will appear as multiple row and datatable dont accept it.. If i remove that foreign key linkage, my datatable will display without any error.
In this case, what i want is, how to select aspnetusers table without pulling out its foreign table. For eg
db.AspNetUsers.Select(x=>x.AspNetUsers).ToList();
Turn off the LazyLoading. So that the children will not be fetched automatically.
try doing something like this (good for keeping the return object light and leave behind any unwanted columns):
(I have just made up some col name, but you get the idea.)
var result = (from a in db.AspNetUsers
select new AspNetUser { Name = a.Name,
othercol1 = a.othercol1,
othercol2 = a.othercol2,
}).ToList();
Footnote: In reality it is generally not good practice to return the actual db Entity to the front end so you might want to have your own Data Transfer Objects (DTO).
You configured that in the mappings using the Fluent API's methods
HasOptional
HasMany
Ignore
etc. But normally, I create schema-bound views in database and then map that in EF. It works really well in cases when we're only interested in a flattened query without all the joints.
Or use Linq to EF projections as JonhB's answer...
var result = (from a in db.AspNetUsers
select new AspNetUser { Name = a.Name,
...
}).ToList();
Just make sure you don't call ToList on db.AspNetUsers because that would materialize the query on AspNetUsers and all it's foreign key references and as result the projection is done in-memory after the query returns
I use Entity Framework 4 on C# Winforms.
I have a SQL Server database with 2 tables like this:
Users table:
UserId (int) (PK)
UserName
Products table:
ProductId (int)(PK)
ProductTitle
UserId1 (int) (foreign key referencing `UserId` in `Users` table)
UserId2 (int) (foreign key referencing `UserId` in `Users` table)
I am modeling SQL Server database in my C# project with Entity Framework (including foreign key columns in model).
Then I get records with this code:
Entities dbEnteties = new Entities();
dbEnteties.ContextOptions.LazyLoadingEnabled = false;
var dbe = dbEnteties.Products.Include("Users");
var result = dbe.ToList();
When I get records from database I see that the UserId1 field has data but UserId2 field is Null.
What's wrong with my C# code? And how can I solve this problem?!
It's perfectly okay for you to have two foreign keys in the Products table pointing to the Users table. I do this all the time, and your reason for doing it is fine.
Since you have turned Lazy Loading off, you need to explicitly ".Include" the navigation properties if you want the query to automatically load them. You're going to have to figure out what the names are for the navigation properties that Entity Framework created automatically for you. I'm assuming you are using the "Database First" model. If that's the case, then double click on your .EDMX file and look at the Products table. You should see a section there called "Navigation Properties". They might be called "User" and "User1". If this is the case, then you need to do the following. Since you have two separate relationships between the tables, you will need two separate ".Include" statements:
dbEnteties.Products.Include(product => product.User);
dbEnteties.Products.Include(product => product.User1);
(Make sure to include using System.Data.Entity; at the very top of your file, otherwise the lambda syntax will not work.)
im using Code First Entity Model with Web API Asp.Net
i need 3 tables in total
The First table(Table1) contains some information with a unique Id lets say it is like
string id
string model
The second Table (Table2)contains some information about the user. lets say it is
string Id
string name
string company
now i need a third table. which would only work as a joining table and would contain
Table1 ModelInfo
Table2 UserInfo
but it is showing me an error that table cannot be created with out a unique id. but as my architecture is i dont need a unique id
what should i do?
or do i need to change my architecture?
Your question is general EF CodeFirst Many-to-Many relationship.
Suggested readings:
EF CodeFirst - Build Many-to-Many relationships
Composite Key - question on StackOverflow
How to have Many to Many association in EF CodeFirst
I'm trying to take an object and design an SQL table to store it. The object has a member called "Roles" which is an enum that has 4 values. Each object can have several different roles.
Right now, I've taken the enum and created an eponymously named SQL table out of it and added the 4 roles to it. Now I'm trying to design the object table and I can't figure out how to get the many to many relationship working for it. I would also like it to work well with Linq-to-SQL. It would be nice to have the enum preserved, but if not an array of strings could also work.
In short, I need a table that has a many-to-many between Roles and Object.Roles (or Object.Roles[])
Thanks!
Generally, Many-To-Many relationships in Linq2SQL (and Entity Framework) are created by introducing an association table, with only the primary keys from the two tables you want to link, and where each row corresponds to an association.
Since your Role and Object.Role could be difficult to keep apart in an attempt to explain this, I'll give another example: in a school, each teacher can have many students, and each student can have many teachers. The table structure to represent this would then be
Teachers Students StudentTeacherRelations
******** ******** ***********************
TeacherId StudentId TeacherId
FirstName FirstName StudentId
etc... etc...
Now, Linq2SQL and EF are both smart enough to recognize this as a many-to-many relationship, and introduce navigation properties in your model. A POCO with appropriate properties for the Student object could look like this:
public class Student
{
public int StudentId { get; set; }
public string FirstName { get; set; }
// etc
public IEnumerable<Teacher> Teachers { get; }
}
If this is set up correctly, the O/R mapper will automatically populate the Teachers property.
Update: In response to comments, here is a how I'd structure the rest of the database if I wanted to include a scenario where each teacher can give some students homework consisting of a number of questions:
HomeworkAssignments Questions Answers
******************* ********* *******
HomeworkAssignmentId (pk) QuestionId (pk) AnswerId (pk)
... HomeworkAssignmentId (fk) QuestionId (fk)
... StudentId (fk)
...
StudentHomeworkAssignmentRelations TeacherHomeworkAssignmentRelations
********************************** **********************************
StudentId (fk) Teacherid (fk)
HomeworkAssignmentId (fk) HomeworkAssignmentId (fk)
As you can see, there's quite a lot of tables here. However, this structure allows you to let each teacher create many homework assignments, and then hand each assignment out to a number of students. You'll have a navigational property Student.HomeworkAssignments of type IEnumerable<HomeworkAssignment>, via which you can find all the questions a student has to answer. For each posted answer, you store a row in the Answers table, which is linked to both questions and students by 1-to-many relations - each answer can belong to one question only, and be given by one student only.
The key here is that you don't need to be able to access each answer given by a student directly - in both Linq2SQL and EF it's possible to request data from many tables at once in various ways. One of those ways is
var answersToTheLastExam = context.Students
.SelectMany(s => s.HomeworkAssignments)
.OrderBy(ha => ha.Date) // this might need modifying to get the last one first
.First(ha => ha.Questions.Count() > 0)
.SelectMany(ha => ha.Questions)
.SelectMany(q => q.Answers)
.Where(a => a.StudentId == myId)
Note that this code is untested an might not work as I say it will. I'm just trying my best off the top of my head here =)
Roles
Id Pk
ObjectRoles
Id Pk
ObjectRoleRoles
RolesId Pk & FK
ObjectRolesId PK & FK
var result = (from orr in _context.ObjectRoleRoles
inner join r in _context.Roles on orr.RolesId equals r.Id
inner join or in _context.ObjectRoles on orr.ObjectRolesId equals or.Id
where orr.RolesId equals 1
select r).ToList();
The fields in ObjectRoleRoles must be both the PK and FK.
Can anyone help, I have been using linq2sql with great success using my associations (foreign keys) to provide inner joins etc...
for example this, works great, the color is stored in a table called Color which has association so i pick it up via Color.Description - Excellent. Same for StructureType its actually an association so i pick it up via the structureType association and the field Description which is in the StructureType table
from v in Houses
select new
{
Id = v.Id,
Color = v.Color.Description,
StructureType= v.StructureType.Description,
Price = v.StructureGroup.StructureGroupTariffs. // doesn't provide anything more only Any, All etc
}
The problem being is that Price i am trying to link, so houses has a Association to StructureGroup which has a association to StructureGroupTariffs but i don't get any more options..
StructureGroupTariffs in an Interlinking table that links StuctureGroup to Tariffs,
I actually did a test here with the interlinking table in Linq and it works! like so
from g in StructureGroupTariffs
select new
{
Price = g.Tariff.Price
}
So i am a little confused, why (see above) this
Price = v.StructureGroup.StructureGroupTariffs.
only returns methods like Any, All etc but not the association....
Can anyone help please
StructureGroupTariffs is an EntitySet not an EntityRef, i.e. it contains many objects rather than a single object. You can't extract the 'many' into the 'single' that you are assembling in your query.
EDIT
I suspect that your House table has a StructureGroup and that there is a Tariffs table, in between is a StructureGroupTariffs table that holds FK references to each of the other tables allowing there to be many tariffs for each structure group (irrespective of whether there actually are many tariffs). Hence Linq using an EntitySet to refer to the StructureGroupTariffs.