I have an entity whose reference is a composite of an identifier and an environment. I want to implement a function to allow the user to pass a list of tuples of (ID, Environment) and return back the required entities. Is it possible to use Contains() in such scenarios? How? With a simple reference, it is as simple as
model.MyEntities.Where(e => myIds.Contains(e.Id))
EDIT: To clarify, I am not looking for how to use Contains() method to retrieve a list of IDs; the line I wrote above does this. What I am looking for is to be able to retrieve a list of entities matching tuples of (ID, Environment) rather than just ID.
Latest version of Entity Framework allows you to do a Contains on an array of primitive types (I think it works on an IEnumerable too now, I haven't tried).
If you match solely on your Id (ie, your match is good if one of the Tuple's ID is the MyEntity.Id, this will work (I'm using Tuple losely here as your case seems to be an actual object; Tuple only has ItemN properties):
var containedIds = yourListOfTuples.Select(t => t.Id).ToArray();
model.MyEntities.Where(e => containedIds.Contains(e.Id));
This will effectively translate into a WHERE ... IN ([the Ids in containedIds]) statement in SQL.
Related
In entity framework 6 is it possible to mix raw SQL generated dynamically with IQueryable like this:
IQueryable<Tree> tree_query = context.Trees.Where(t=>t.Height> 2);
IEnumerable<int> tree_additional_filter = context.Database.SqlQuery<int>("SELECT Id FROM TREE_VIEW WHERE Width < 1");
IQueryable<Tree> final_query = from tree in tree_query
join filtering_tree in tree_additional_filter on filtering_tree.id equals tree.id
select tree;
This produces a result as is, but the "tree_additional_filter" is executed in the database in order to construct the final_query. How can I make entity framework construct only one query from this?
I need this to create dynamic filter fields which work together with static ones.
I also tried creating TREE_VIEW entity with only Id column, which I know to always be there.
Used System.Linq.Dynamic to construct "where" clause dynamically on a TREE_VIEW entity which has only Id property, but apparently expressions can't be built if properties do not exist in the Type.
In entity framework 6 is it possible to mix raw SQL generated dynamically with IQueryable like this:
No. Notice that Database.SqlQuery returns an IEnumerable<T>, not an IQueryable<T>. Therefore any additional query expressions will be executed against the query results using LINQ to Objects.
Query Composition with raw SQL queries was introduced in EF Core.
I managed to do it.
Using Dynamic type generation to create a type (NewDynamicType) from fields which I got selecting top 1 from my TREE_VIEW. Attached the NewDynamicType to the db context via DbModelBuilder.RegisterEntityType in OnModelCreating.
With System.Linq.Dynamic then I could construct IQueryable selecting from context.Set(NewDynamicType) any fields the user wants to filter by.
Join into final_query like in my question.
Now my HTML form gets fields from the database view and in each distibution I can have different filters defined without having to write any c#.
I am very new with C# and need some help. I am working on someone elses code and they are pulling data from a Model. I am trying to join two tables and need to use Include but the error is '==' cannot be applied to Guid and IQueryable. Could someone help with this please. Thanks in advance!
Yes, I am.
.Where() represents your filter. .Select() represents what you want back. If you just want the entities back you don't need a .Select().
If you have an association between menu items and MenuItemProgramData, for example, a MenuItem holds a reference to a MenuItemProgramData then you don't even need the first ID select statement:
return context.DbMenuItems
.Where(x => x.MenItemsProgramData.Plu == plu);
Note: If your context defines DbSet<T> for your various top level entities, you can just use context.Ts rather than .GetItems<T>.
If the relationship exists then this is the preferred approach. Let SQL do the work. The consumer of your method can further .Select() the applicable data, sort it, paginate it, and even append .Include() if you do want to interact with the entire entity graph.
If you don't have a relationship between the menu item and that program data, and know that the # of item IDs from the first query will remain relatively small (say, sub-100) then:
var itemIds = context.DbMenuItemProgramDatas
.Where(x => x.Plu == plu)
.Select(x => x.MenuItemId)
.ToList();
Without the .ToList() you are dealing with an IQueryable which EF would potentially still attempt to translate to SQL statements when later consumed. By using .ToList() it will execute the SQL and populate a List<int>. (Assuming the menu item ID is an int)
To get the IQueryable menu item data rows:
return context.DbMenuItems
.Where(x => itemIds.Contains(x.Id));
And that is it.
Edit: Based on the comment "I want to return a field named ParentId to know if it is empty or not. That's all but I need both tables linked to get that answer."
Additionally, looking back at the original code, the naming of the method is a bit misleading. GetItemProgramDataForSubItems implies returning MenuItemsProgramData rather than MenuItems... However, if ParentId is a property of MenuItem, then the caller of this method can use:
var hasParentId = context.GetItemProgramDataForSubItems(plu)
.Any(x => x.ParentId.HasValue);
If the ParentId is on the MenuItemsProgramData:
var hasParentId = context.GetItemProgramDataForSubItems(plu)
.Any(x => x.MenuItemsProgramData.ParentId.HasValue);
Beyond that, you may want to elaborate on what your entities and relationships look like, and what exactly you aim to accomplish from your method or business logic.
I'm using Entity Framework 6.
I want to run a stored procedure that returns a non entity object (3 colunms per row)
using(var dbContext = new DBContextEntity())
{
var queryProducts = dbContext.Database.SqlQuery<DataTable>("dbo.GetProductByDesc #q", query);
}
How to get that data as DataSet or anonymous object that I can iterate that?
As far as I know EntityFramework does not provide anonymous object materialization. The reason for that is that it probably generates IL code for each type and caches it (or just does a plain PropertyInfo caching).
The solution is to just create a simple class with properties you need matching the names of the stored procedure result set and use this class as a generic parameter for SqlQuery.
Edit:
SqlQuery implements IEnumerable and when you iterate over it, it executes automatically in thge current thread. To iterate the result you can for example:
foreach(var product in queryProducts)
{
// do something with each product here
}
You can also pass a list of product class instances to a function expecting it:
ShowProducts(queryProducts.ToList());
You can also make the query run in background and return you a list of Product after it has finished, more information about asynchronous fetching can be found here: http://www.codeguru.com/csharp/.net/net_framework/performing-asynchronous-operations-using-entity-framework.htm
Like #Too said, it is best to define a POCO class with properties corresponding to the field names and datatypes returned by the StoredProcedure or other SQL statement.
It is generally better to avoid the use of DataSets in any new development work you are doing. They do have their uses but have a performance penalty in high throughput scenarios which the POCO's clearly avoid.
If the attraction for DataSets is the ability to easily serialize the data over the wire or to a file for later use, then the various serialization frameworks will help you with that eg DataContractSerializer, Newtonsoft.Json, etc.
This also allows for portability if the POCO is defined in a PCL (Portable Class Library).
If you must use DataSets, I would rather use typed DataSets. The DataRow's can be used as the POCO in #Too's answer, since they have a default constructor. Just be careful of nulls and their unique treatment in fields other than String.
I want to dynamically query an object with System.Linq.Dynamic.
var selectData = (from i in data
select i).AsQueryable().Where("Name = #0","Bob1");//This works fine with a non-entity object
I know that we cannot project onto a mapped entity. I believe that is the reason this code fails
foreach (var item in rawQuery.ObsDataResultList)
{
var propertyData = (from i in item
select i).AsQueryable().Where("PropertyName = #0", "blah");
}//item is a Entity Complex Type
Error
Could not find an implementation of the query pattern for
source type 'ClassLibrary1.Model.bhcs_ObsData_2_Result'. 'Select' not
found.
Given the fact that I need to specify the PropertyName at runtime, I don't see any way to project with an anonymous type or a DTO.
I don't need to retain any of the Entity functionality at this point, I just need the data. Copying the data onto something that is queryable is a valid solution. So, is it possible to query entity framework with dynamic LINQ?
And here is the entity class header (the thing I'm trying to query, aka the item object)
[EdmComplexTypeAttribute(NamespaceName="MyDbModel", Name="blah_myQuery_2_Result")]
[DataContractAttribute(IsReference=true)]
[Serializable()]
public partial class blah_myQuery_2_Result : ComplexObject
{
First of all, let me clarify that System.Linq.Dynamic is not a full fledged Microsoft product. It is just a sample we release some time ago, and we don't thoroughly test different LINQ implementations to work correctly with it. If you are looking for a fully supported text-based query language for EF ObjectContext API you should take a look at Entity SQL instead.
Besides that, if you want to use System.Linq.Dynamic and you are ok with testing yourself that you don't hit anything that will block your application from working, then I'll try to see if I can help. I am going to need additional information since I am not sure I understand everything in your code snippets.
First of all I would like to understand, in your first example what is "data" and where did it come from? In your second snippet, what is "rawQuery" and where did it come from? Besdies, what is rawQuery.DataResultList and what is rawQuery.ObsDataResultList?
Also regarding your second snippet, it seems that you are trying to compose with query operators on top of an object that is not actually of a query type (although that doesn't explain the error you are getting given that you are calling AsQueryable the compiler should have complained before that bhcs_ObsData_2_Result is not an IEnumerable nor a non-generic IEnumerable).
In your propposed answer you are saying that you tried with ObjectResult and that seemed to help. Just be aware that ObjectResult is not a query object and therefore it won't allow you to build queries that get send to the server. In other words, any query operators that you apply to ObjectResult will be evaluated in memory and if you don't keep this in mind you may end up bringing all the data from that table into memory before you apply any filtering.
Query ObjectResult<blah_myQuery_2_Result> directly instead of the item blah_myQuery_2_Result. For example
var result = (from i in rawQuery.DataResultList
select i).AsQueryable().Where("CreatedDTM > #0", DateTime.Now.Subtract(new TimeSpan(30, 0, 0, 0)));
I'm reading about the Entity Framework 4.0 and I was wondering why should I create a complex type and not a new Entity (Table) and a relation between them?
The perfect example is an address. Using a complex type for an address is much easier to deal with than a new entity. With complex types you do not have to deal with the Primary Key. Think about accessing an address how many common types of entities would have an address (Business Units, People, Places). Imagine populating many peoples addresses and needing to set a key for each one. With complex types you simply access the internal properties of they type and you're done. Here is an MSDN link of an example. http://msdn.microsoft.com/en-us/library/bb738613.aspx
This question has been here a while already, but I'm going to add an answer anyway in the hopes that the next poor sob that comes along knows what he's in for.
Complex types do not support lazy loading, at least not in EF 4.3. Let's take the address situation as an example. You have a Person table with 15 columns, 5 of which contain address information for certain individuals. It has 50k records. You create entity Person for the table with a complex type Address.
If you need a list of names of all individuals in your database you would do
var records = context.Persons;
which also includes addresses, pumping 5*50k values into your list for no reason and with noticeable delay. You could opt to only load the values you need in an anonymous type with
var records = from p in context.Persons
select new {
LastName = p.LastName,
FirstName = p.FirstName,
}
which works well for this case, but if you needed a more comprehensive list with, say, 8 non-address columns you would either need to add each one in the anonymous type or just go with the first case and go back to loading useless address data.
Here's the thing about anonymous types: While they are very useful within a single method, they force you to use dynamic variables elsewhere in your class or class children, which negate some of Visual Studio's refactoring facilities and leave you open to run-time errors. Ideally you want to circulate entities among your methods, so those entities should carry as little baggage as possible. This is why lazy loading is so important.
When it comes to the above example, the address information should really be in a table of its own with a full blown entity covering it. As a side benefit, if your client asks for a second address for a person, you can add it to your model by simply adding an extra Address reference in Person.
If unlike the above example you actually need the address data in almost every query you make and really want to have those fields in the Person table, then simply add them to the Person entity. You won't have the neat Address prefix any more, but it's not exactly something to lose sleep over.
But wait, there's more!
Complex types are a special case, a bump on the smooth landscape of plain EF entities. The ones in your project may not be eligible to inherit from your entity base class, making it impossible to put them through methods dealing with your entities in general.
Assume that you have an entity base class named EntityModel which defines a property ID. This is the key for all your entity objects, so you can now create
class EntityModelComparer<T> : IEqualityComparer<T> where T : EntityModel
which you then can use with Distinct() to filter duplicates from any IQueryable of type T where T is an entity class. A complex type can't inherit from EntityModel because it doesn't have an ID property, but that's fine because you wouldn't be using distinct on it anyway.
Further down the line you come across a situation where you need some way to go through any entity and perform an operation. Maybe you want to dynamically list the properties of an entity on the UI and let the user perform queries on them. So you build a class that you can instantiate for a particular type and have it take care of the whole thing:
public class GenericModelFilter<T> : where T : EntityModel
Oh wait, your complex type is not of type EntityModel. Now you have to complicate your entity inheritance tree to accommodate complex types or get rid of the EntityModel contract and reduce visibility.
Moving along, you add a method to your class that based on user selections can create an expression that you can use with linq to filter any entity class
Expression<Func<T, bool>> GetPredicate() { ... }
so now you can do something like this:
personFilter = new GenericModelFilter<Person>();
companyFilter = new GenericModelFilter<Company>();
addressFilter = new GenericModelFilter<Address>(); //Complex type for Person
...
var query = from p in context.Persons.Where(personFilter.GetPredicate())
join c in context.Companies.Where(companyFilter.GetPredicate()) on p.CompanyID = c.ID
select p;
This works the same for all entity objects... except Address with its special needs. You can't do a join for it like you did with Company. You can navigate to it from Person, but how do you apply that Expression on it and still end up with Person at the end? Now you have to take moment and figure out this special case for a simple system that works easily everywhere else.
This pattern repeats itself throughout the lifetime of a project. Do I speak from experience? I wish I didn't. Complex types keep stopping your progress, like a misbehaved student at the back of the class, without adding anything of essence. Do yourself a favor and opt for actual entity objects instead.
Based on Domain Driven Design Concepts, Aggregate root could have one or more internal objects as its parts. In this case, Internal objects - inside the boundary of Aggregate Root - does not have any KEY. The parent key will be applied to them or somehow like this. Your answer returns to the benefit of keeping all Parts inside Aggregate root that makes your model more robust and much simpler.