LINQ expression to get the whole content of right table - entity-framework

In my database, I have these two tables with a relationship :
I would like to get the whole content of the "assignee_kanban" column in "assigneekanban" table (which for now contains six names).
Here is the expression I use (in my "Kanban" controller using entity framework) :
public List<Kanban> LoadCard() {
return _context.Kanbans.Include(c => c.IdAssigneeKanbanNavigation).ToList();}
When I try to get the result in my razor page with :
#foreach (var name in Kanbans)
{
<tr>
<td>#name.IdAssigneeKanbanNavigation.AssigneeKanban1</td>
</tr>
}
unfortunatly, the result I get contains only three names : the three names corresponding to the three "id_assignee_kanban" that exist in the "kanban" table.
How can I get all the names contained in the "assignee_kanban" column ?
(I succeed to get the values using assigneekanban controller but for some reason, I want to use kanban controller with the navigation statement)
(project webassembly blazor using .net 6 aspnet hosted)
Thank you for your help.
Here is the content of the "kanban" table (I removed some no important columns for this problem) :
Here is the content of the "assigneekanban" table :
Here is the output :
As we can see, the name "Robert" corresponding to the id n°5 doesn't appaer in the result and the other names appear as many time they exist in the kanban table (of course, I can add a distinct close to avoid duplicate names but it doesn't bring the missing name !).

You need a second query to get all entries from the assigneekanban table. Your current implementation will only get those values from the assigneekanban that have a foreign key entry in the kanban table (Basically doing an INNER JOIN).
public async Task<List<Kanban>> LoadCardAsync()
{
return _context.Kanbans.ToList();
}
public async Task<List<AssigneeKanban>> LoadAssigneesAsync()
{
return _context.AssigneeKanbans.ToList();
}
public async Task LoadEverythingAsync()
{
Kanbans = await LoadCardAsync();
Assignees = await LoadAssigneesAsync();
}
Then in your Razor Page
#foreach (var assignee in Assignees)
{
<tr>
<td>#assignee.AssigneeKanban1</td>
</tr>
}

Related

Saving change to an Entity which is mapped to a View

Can I use Entity Framework to save changes to a view?
I have an entity which is mapped to a View.
[Table("MyView")]
public class MyEntity
{
public long MyEntityId { get; set; }
public string Name { get; set; }
}
The View itself is like this:
CREATE VIEW MyView AS
SELECT
t.MyEntityId,
t.Name,
FROM
MyTable t
Would I be able to use Entity Framework change tracking to save changes to this View? So is something like this possible:
var record = Context.MyEntity.Where(e => e.MyEntityId == 150).FirstOrDefault();
record.Name = "New Name";
Context.SaveChanges();
Looks like Entity Framework does not care if the Entity is mapped to a View or Table... it would just create the same update script. For the example above EF generates the following script:
UPDATE [MyView] SET [Name]=#gp1 WHERE [MyEntityId] = 150
-- #gp1: 'New Name' (Type = String, IsNullable = false, Size = 8)
So EF does not introduce any additional limitation for updating a View... but we still have the RDBMS specific limitations for updating a View... as an example, in SQL Server a view can be updated subject to the following limitations:
If the view contains joins between multiple tables, you can only insert and update one table in the view, and you can't delete rows.
You can't directly modify data in views based on union queries. You can't modify data in views that use GROUP BY or DISTINCT statements.
All columns being modified are subject to the same restrictions as if the statements were being executed directly against the base
table.
Text and image columns can't be modified through views.
There is no checking of view criteria. For example, if the view selects all customers who live in Paris, and data is modified to
either add or edit a row that does not have City = 'Paris', the data
will be modified in the base table but not shown in the view, unless
WITH CHECK OPTION is used when defining the view.

Laravel Eloquent Relationship 3 tables

I am a newbie to Laravel 5.2 and am working on a legacy system and am a bit confused regarding eloquent and would appreciate someone giving me the code.
There are 3 tables:
cards
categories
cards2cat
cards can be part many categories which are kept in cards2cat table.
The cards2cat table has the following structure
id (primary key)
image (card)
category
What I want to do is to have a method in the Cards model called something like getCardsWithCategores which returned the cards info plus the names of the categories from the category table.
The categories table has a key of id and a field category.
Thanks!
Go to your Card2Cats model and add this:
public function categories()
{
return $this->hasOne('App\Categories','id','category');
}
public function cards()
{
return $this->hasOne('App\Cards','id','image');
}
For the query you do this:
$cards = Card2Cat::with('categories','cards')->get();
foreach ($cards as $key => $value) {
echo $value->id.', Card:'.$value->cards->name.', Category:'.$value->categories->category.'<br>';
//$value->cards gives you all column of cards and you can do
//$value->cards->colName
// same goes for $value->categories
}
Make sure the spelling of your classes and table column names are correct before running the code :D

Breeze with stored procedure CLR error

Im trying to call a stored procedure using Entity framework.
If I go direcly to the web api method it works fine, but when calling it from breeze it causes an exception on the metadata method.
The error is :
"Could not find the CLR type for...".
Anyone know how to fix this?
I had the very same issue, but thank God I figured out a solution. Instead of using a stored procedure, you should use a view, as Breeze recognizes views as DbSet<T>, just like tables. Say you have a SQL server table that contains two tables Customers and Orders.
Customers (**CustomerId**, FirstName, LastName)
Orders (OrderId, #CustomerId, OrderDate, OrderTotal)
Now, say you want a query that returns orders by CustomerId. Usually, you would do that in a stored procedure, but as I said, you need to use a view instead. So the query will look like this in the view.
Select o.OrderId, c.CustomerId, o.OrderDate, o.OrderTotal
from dbo.Orders o inner join dbo.Customers c on c.CustomerId = o.CustomerId
Notice there is no filtering (where ...). So:
i. Create a [general] view that includes the filtering key(s) and name it, say, OrdersByCustomers
ii. Add the OrdersByCustomers view to the entity model in your VS project
iii. Add the entity to the Breeze controller, as such:
public IQueryable<OrdersByCustomers> OrdersByCustomerId(int id)
{
return _contextProvider.Context.OrdersByCustomers
.Where(r => r.CustomerId == id);
}
Notice the .Where(r => r.CustomerId == id) filter. We could do it in the data service file, but because we want the user to see only his personal data, we need to filter from the server so it only returns his data.
iv. Now, that the entity is set in the controller, you may invoke it in the data service file, as such:
var getOrdersByCustomerId = function(orderObservable, id)
{
var query = breeze.EntityQuery.from('OrdersByCustomerId')
.WithParameters({ CustomerId: id });
return manager.executeQuery(query)
.then(function(data) {
if (orderObservable) orderObservable(data.results);
}
.fail(function(e) {
logError('Retrieve Data Failed');
}
}
v. You probably know what to do next from here.
Hope it helps.

how do I return entities from delimited list of Ids in EF5 Code First

I want to hydrate a collection of entities by passing in a comma delimited list of Ids using EF5 Code First.
I would previously have created a table function in t-sql, passed in the comma delimited list of Ids, I'd then join this table to the target table and return my collection of records.
What is the most performant way of using EF5 Code First to achieve the same?
Update: I want to avoid having the full set of entities in memory first.
Update2: I'd ideally like the order of the entities to match the delimited list.
I'd say to start out by converting the comma delimited list into a List<int> that contains all of the IDs that you would be going for. At that point, using your particular DbContext class you would do the following:
var entities = db.MyEntities.Where(e => myListOfIds.Contains(e.ID)).ToList();
Note: I only put the ToList at the end there because you were talking about hydrating the collection. Otherwise, with IEnumerable, there will be deferred execution of the query, and so it will not populate right away.
You could do it like this, where you restrict the set of Entity objects by checking if their IDs belong to your list of IDs:
// Dummy list of POCO 'entity' objects (i.e. the Code first objects) just for the sake of this snippet
var entities = new List<Entity>();
entities.Add(new Entity() { ID = 1, Title = "Ent1" });
entities.Add(new Entity() { ID = 2, Title = "Ent2" });
entities.Add(new Entity() { ID = 3, Title = "Ent3" });
// List of ids to match
var ids = new List<int>();
ids.Add(1);
ids.Add(2);
// LINQ:
var selected = (from e in entities where ids.Contains(e.ID) select e).ToList();
Just for completeness, this is the dummy class used above:
// POCO (Code first) object
private class Entity
{
public int ID { get; set; }
public string Title { get; set; }
}

Fetch only key value from EF association

I've set up a many-to-many association between two tables based on a third table that just holds a pair of key values. Now I'd like to do a query that groups the right tables key values by the lefts without needing other data.
LeftTable { LeftID, LeftField1, LeftField2 }
JoinTable { LeftID, RightID}
RightTable { RightID, RightField1, RightField2 }
Is there any way to essentially just query the JoinTable and get all the 'RightIDs' grouped by the 'LeftIDs' without the SQL trying to fetch the fields from either side?
The JoinTable is not an entity in its own right in the model, but is mapped to the association.
I've experimented a bit with both using ObjectQuery and EntityCommand (ESQL) and both seem to still load in the other fields by joining to RightTable which I don't need.
My ESQL looks something like:
SELECT lt.LeftID, (SELECT rt.RightID
FROM NAVIGATE(lt, MyModel.LeftToRightAssoc, RightTable) as rt)
FROM MyEntities.LeftTable as lt;
but the generated SQL is still fetching in RightField1 and RightField2.
Surely there must be a simpler way to do this?
Assuming that your class Left has a navigation property Rights (a collection of Right entities) you could try this:
var list = context.Lefts.Select(l => new
{
LeftId = l.LeftId,
RightIds = l.Rights.Select(r => r.RightId)
});
foreach (var item in list)
{
Console.WriteLine("LeftId = {0}", item.LeftId);
foreach (var rightId in item.RightIds)
{
Console.WriteLine("RightId = {0}", rightId);
}
}
You would get a collection of anonymous type objects where each element has the LeftId and a collection of corresponding RightIds. This query should not touch the other fields like RightField1, etc. Instead of an anonymous type you could also create your own custom type and then project into this type in the query above.