How to apply a condition to a specific table in every request on Entity Framework? - sql-server

I have a many-to-many structure mapped to entity framework. This is a sample of what it looks like:
User UserTag Tag
------- -------- -------
IdUser(PK) IdUserTag(PK) IdTag(PK)
Name IdUser(FK) TagName
Desc IdTag(FK) Active
Now, I needed to exclude from any request of any method the viewing of Tags that were Active=false.
First, I tried doing it manually in every method, like:
public User GetById(int id)
{
var item = UserRepository.GetById(id); //This is just a repository that calls the EF context
//EF automatically maps it to the *UserTags* property
foreach(var tag in item.UserTags)
{
if(tag.Tag.Active == false)
item.UserTags.Remove(tag);
}
}
But it throws the following exception:
The relationship could not be changed because one or more of the foreign-key properties is non-nullable
So, I wanted to know if there's a way to conditionaly filter every request made to a specific table, whether it is select or a join request.

Try this in your GetById method:
var user.UserTags = dbContext.Entry(user)
.Collection(u => u.UserTags)
.Query()
.Where(ut => ut.Active == true)
.ToList();

The supplied code fails because it is attempting to remove items from the data entities not the list. If you want to pass the data entity around instead of the data model, you need to not use Remove. Something like the below (untested should work).
tags = item.UserTags.Where((ut) => ut.Active).ToList();
This line will get you a list of data entities that are active. However, you should really map all of this into a data model (see AutoMapper) and then you would not be removing items from the database.

Related

How to get Entry Id for a Newly Created Entity in Breeze

i want to create a registration form that will be in batch with a continuation button, getting the id of the entry will help me to call the save method.
I want to immediately get the primary key of a new Entry Created using BreezeJS, Pls i need help on this.
Thanks
Not entirely sure I understand your question, but it sounds like you want to get the id of a newly saved record immediately after the save. If so then the answer below applies.
When the save promise resolves it returns both the list of saved entities as well as a keyMappings array for any entities whose ids changed as a result of the save. i.e. a mapping from temporary to real ids. i.e. (Documented here: http://www.breezejs.com/sites/all/apidocs/classes/EntityManager.html#method_saveChanges)
myEntityManager.saveChanges().then(function (saveResult) {
// entities is an array of entities that were just saved.
var entitites = saveResult.entities;
var keyMappings = saveResult.keyMappings;
keyMappings.forEach(function(km) {
var tempId = km.tempValue;
var newId = km.realValue;
});
});
On the other hand if you have an entity and you just want its 'key' you can use the EntityAspect.getKey method. (see http://www.breezejs.com/sites/all/apidocs/classes/EntityAspect.html#method_getKey)
// assume order is an order entity attached to an EntityManager.
var entityKey = order.entityAspect.getKey();

What kind of query in LINQ do I have to make to get a custom List that contains Lists of objects?

What I'm trying to do is to find the best and fastest way to obtain a collection of objects from a query so I can parse them into JSON and send them through a WCF webservice. I have an entity that is related to two other entities, the properties as shown in my edmx are like this:
Event
EventId
Date
Acceleration
Intensity
DeviceId
BlockId
Device
Block
Device
DeviceId
Alias
ClusterId
Cluster
Events
Block
BlockId
DateStart
DateEnd
Events
What I want to get List of Lists of the Events associated to every Block, each Block's Events being represented by a List, but I only want to get the EventId, Date, DeviceId, BlockId, Acceleration and Intensity of every Event, because I want to avoid the circular reference that would be caused for trying to parse the Device and Block properties in each Event object.
I tried something like
var result = (from d in context.Block select (d.Events)).ToList();
but this only returns a List containing Event objects in every Block, but I don't know how to get the information I specified of every Event in every Block.
How can I specify in my query the information I want to retrieve?
I think it will be easier using Method Based query:
var result = context.Block.Select(b => b.Events.Select(e => new
{
e.EventId,
e.Date,
e.DeviceId,
e.BlockId,
e.Accelleration,
e.Intensity
}).ToList()).ToList();
You need to use a groupJoin
Here is an example
var teamsandriders = teams.GroupJoin(riders, Team => Team.name, Rider
=> Rider.TeamName, (team, teamRiders) => new {Team = team.name, riders = teamRiders.Select(rider => rider.name)});

how to display the data returned by get_by_user_id() in DataMapper Code Igniter?

I am new to code igniter data mapper. I have a table called user, and I am trying to retrieve data from the database table and show them to the user.
Here is what I have in the model:
$u=new User();
$results=$u->get_by_user_id($id);
//$results here will be set to huge bunch of none sense data( which also includes the row that I am looking for as well)
if ($u->exists())
{
foreach ($results->all as $row){
$data['user']['first_name']=($row->user_first); //this where I am stuck ..
$data['user']['last_name']=($row->user_last);//this is also where I am stuck..
}
I don't know how to treat results to get a required fields I am looking for and store them in the $data I am passing to the user to view.
Thanks!
When you call get_by_x() on the model, the fields will be populated with data and you can access them like this:
$u = new User();
$u->get_by_user_id($id);
if($u->exists())
{
// you can access the table columns as object fields
$data['user']['first'] = $u->first;
$data['user']['last'] = $u->last;
}
else
{
$data['error'] = 'No such user!';
}
Have a look at the documentation which is really helpful: see Get and Get By.
Also, DataMapper expects all tables to have an id column: see Table Naming Rules. If your column is named id you should then call $u->get_by_id($id) instead of $u->get_by_user_id($id).

Loading a Child (Navigation Property) Entity not working

I am having a very tough time with this one. I have a Navigation property called Attachment that is part of an entity called ContentChannel. ContentChannel is a many to one relationship with KioskType.
In my domain service extension class, I have the following query:
public IQueryable<ContentChannel> GetContentChannelFromKioskType( long kioskTypeID )
{
var returnSet = (from cc in ObjectContext.ContentChannels.Include( "Attachment" )
join pcc in ObjectContext.PublishedContentChannels on cc.ContentChannelID equals pcc.ContentChannelID
where pcc.KioskTypeID == kioskTypeID
select cc);
return returnSet;
}
And this works just fine for returning the list of ContentChannels. But the Attachment in each ContentChannel is null.
I have tried [Include] on the attachment property in my ContentChannel metadata class, in conjuction with ContentChannels.Include("Attachment") in the above query- no luck, Attachment is always null.
I dug more and then found something to explicitly load my child item:
ObjectContext.LoadProperty( returnSet, "Attachment" );
But this generates the following error:
Cannot explicitly load property for entities that are detached. Objects loaded using the NoTracking merge option are always detached.
Is it because I'm doing a join that things are wonky and the Include doesnt work? What do I need to do? These attachments need to get loaded when I get a ContentChannel!
Any thoughts?
By including the join in your query, you've changed the shape of the query, after the Include. So the Include is discarded. But you don't need the join:
public IQueryable<ContentChannel> GetContentChannelFromKioskType( long kioskTypeID )
{
var returnSet = (from cc in ObjectContext.ContentChannels.Include( "Attachment" )
where cc.PublishedContentChannels.Any(pcc => pcc.KioskTypeID == kioskTypeID)
select cc);
return returnSet;
}

Zend Many to Many Relationship

I want to retrieve all the data from 3 tables
users , properties and users_properties.
So I decided I would use the manytomanyRowset. But to my surprise I get the data from the properties and users_properties table but no data from the users table. Why is that? I need some columns from the users table is there a way to tell the manytomanyrowset function that I need the data from the current table as well?
this is my function
public function fetchRegisteredProperties()
{
$userTable = $this->getTable();
require_once APPLICATION_PATH . '/models/DbTable/UsersPropertiesDB.php';
require_once APPLICATION_PATH . '/models/DbTable/PropertiesDB.php';
$propertiesRowset = $table->fetchAll();
$allProperties = array();
foreach ($propertiesRowset as $row) {
$propertiesRowset = $row->findManyToManyRowset(
'Model_DbTable_Properties','Model_DbTable_UsersProperties');
$allProperties = array_merge($tempArray,$propertiesRowset->toArray());
}
return $allProperties;
}
thanks in adavance
I designed and coded the table-relationships features in Zend Framework.
The answer to your question is no, the findManyToManyRowset() method only fetches rows from the related table, it does not merge them into the corresponding Row object. The reason is that a Row object in ZF can save() itself back to the database, and if you add fields it won't know what to do with them.
So you should implement a custom Row object to hold both user fields and the collection of user properties -- store the user properties as a Rowset object.
Then extend __get() and __set() so that it knows how to map fields into the correct array when you read or write object properties. That is, if one tries to read or write a field that isn't part of the user row, it falls back to the user properties Rowset.
Also extend save() to save not only the current row, but also call save() on the Rowset of user properties.

Resources