cannot cast from List to EntityCollection - c#

I'm trying to update an entityCollection
Here is my linq:
itemFromDb.MamConfigurationToBrowser_V1 =
(EntityCollection<MamConfigurationToBrowser_V1>) itemFromDb.MamConfigurationToBrowser_V1
.Select(browserEfItem =>
FillFromUi(browserEfItem,
item.MamConfigurationToBrowser_V1
.Single(browserUiItem => browserUiItem.BrowserVersionId == browserEfItem.BrowserVersionId)))
.ToList().AsEnumerable();
However I get a runtime casting error:
Unable to cast object of type
'System.Collections.Generic.List1[Conduit.Mam.MaMDBEntityFramework.MamConfigurationToBrowser_V1]'
to type
'System.Data.Objects.DataClasses.EntityCollection1[Conduit.Mam.MaMDBEntityFramework.MamConfigurationToBrowser_V1]'.
Why is that? As I'm doing linq to entity, no?

You are creating a List<MamConfigurationToBrowser_V1> with your second-last call ToList() in your Linq expression and then you try to cast this list to an EntityCollection<MamConfigurationToBrowser_V1. I would recommend to create a new EntityCollection and add the results from the LINQ query to this collection, like so:
var collection = new EntityCollection<MamConfigurationToBrowser_V1>();
var processedItems = itemFromDb.MamConfigurationToBrowser_V1
.Select(browserEfItem =>
FillFromUi(browserEfItem,
item.MamConfigurationToBrowser_V1
.Single(browserUiItem => browserUiItem.BrowserVersionId == browserEfItem.BrowserVersionId)))
.ToList();
foreach(var item in processedItems)
{
collection.Add(item);
}
Important: your code seems to mix database concerns with business logic and personally I never used an EntityCollect<T> directly in my code. I don't know your context but maybe you should consider using the Repository and Unit of Work pattern. Search for them on Google.

ItemFromDB is an unique object? I mean that if itemFromDB is not a list, yo are trying to convert a unique object to a list.
instead of .ToList().AsEnumerable() you can try to use .FirstOrDefault().

Related

Get the first item property with lambda expression

In C#, I'm going to use lambda expression, I have such a code
var item = dbContext.Products.ToList();
How can i get a property of Product table.
try this
var item = dbContext.Products.FirstOrDefault().Name;
With Lamba expression normally you can access and read information from "list" or in this case, IQueryable objects.
With your code you can access to objects with something like this:
var item = dbContext.Products.FirstOrDefault();
// item may be null if products table is empty
if (item != null)
{
// now you can access at object properties (example)
var data = item.PropertyData;
}
Your question may open others way that including reflection for exploring object without well known class definition...
If you want to get the property for each product with lambda expression, then you should make a lambda expression like x => x.Prop when you do your query
if (dbContext.Products != null){
var list = dbContext.Products.ToList();
var query = list.Select(x => x.Prop //your property will appear here...
}

Convert IEnumerable<T> to collection of dynamically generated objects

Recently I asked a more general question about getting properties of model through foreign key.
Now I moved a bit further but still have no idea how transform objects on the fly.
What I've got is an IEnumerable collection which I get through repository
regionRaw = unitOfWork.RegionRepository.Get(
keyOrder: q => q.OrderBy(d => d.RegionID),
filter: p => p.FullName.Contains(lastname) || p.ShortName.Contains(lastname),
orderBy: jtSorting,
includeProperties: "District, ISO31662, GOST767Region");
Further I am going to export data from this collection to Excel. So I need a select statement that gets all the fields I need.
dt = regionRaw
.Select(x => new
{
ISO = x.ISO31662.GOSTName,
DistrictName = x.District.ShortName
})
I do not want to enumerate all the fields I need like on the top.
I am able to make a method that recognizes which of the fields have simple values and which have objects referenced through foreign key. And then that method will return a list of properties.
Now I need some way to write something like a foreach inside select. I see something like this:
dt = regionRaw
.Select(x => new
{
foreach (prop in propList)
{
prop.PropertyName = x.GetType()
.GetProperty(prop.TableName)
.GetValue(x, null).GetType()
.GetProperty(prop.PropertyName)
.GetValue(
x.GetType().GetProperty(prop.TableName).GetValue(x, null),
null);
}
}
Where propList is a collection of properties that I get before.
I do totally realize that upper code is more a pseudo-code but I have no idea how to realize this in .NET.
So if you can suggest some solution for this task I will be very grateful. Or maybe you could explain that all this is a bad idea and shouldn't be realized.
You wont be able to create an anonymous type with dynamic properties as anon types are created during compile and your properties are created during execution.
But why do you need strongly typed properties if you're not going to code against them, as you wont know them until someone executes the query?
Expando object may be of use to you?http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx

Is there any way of knowing the content of an IQueryable object without using Reflection?

I have to work with a given class "QueryGenerator" that generates dynamic queries from selected Tables and Columns by the user using a StringConnection and a Provider. Anyways, i don't have to know the implementation of the class but i have to use it and i'm stock.
At the end, the "QueryGenerator" returns the result query as an object, the only thing that i know (because i use Reflector on the class) is that i can do an IQueryable cast on that query result. Here is an example:
var result = (IQueryable)myQueryGenerator.Result;
And for knowing the content of result, i have to use Reflection.
So, is there any better way of finding out the content of result , and, for example, fill a DataSet with it?
No, there isn't.
IQueryable could return objects of different types (e.g. if you query against an array of objects). In this extreme case you would need to determine the type for each individual item in the enumerated query as you access them.
Example code to demonstrate this scenario:
object[] objs = new object[3]{ "string", 78, DateTime.Now };
var q = objs.AsQueryable().Skip(1).Take(2);
foreach( var o in q )
{
var t = o.GetType();
}

How to cast an Collection<x> to an IQueryable<x>

I am trying to set up a moq, but i am needing to create a fake IQueryable. i made a Collection but i am at a loss of how to cast that to an IQueryable.
Collection<DetailDataEntity> DetailDataEntityCollection =
new Collection<DetailDataEntity>();
DetailDataEntity DetailDataEntity = new DetailDataEntity();
DetailDataEntity.FeedTypeID = 1;
DetailDataEntityCollection.Add(DetailDataEntity);
_mockRepository.Setup(x => x.GetDetail(It.IsAny<Int32>(),
It.IsAny<Enum.FeedTypeEnum.FeedType>()))
.Returns(DetailDataEntityCollection);
Just call AsQueryable on your collection.
_mockRepository.Setup(x => x.GetDetail(It.IsAny<Int32>(),
It.IsAny<Enum.FeedTypeEnum.FeedType>()))
.Returns(DetailDataEntityCollection.AsQueryable());
I had a simple ICollection object and found that this worked for me:
var tapSettings = xfmrTapSettings.ToList().AsQueryable();
I had to use ToList in front of AsQueryable to make it work.

"Member access 'DataType MemberName' of 'Namespace.ClassName' not legal on type 'System.Collections.Generic.IEnumerable`1[Namespace.ClassName]."

I would love a solution to my current problem, but I would love EVEN MORE if I can understand what that error actually means.
I have LINQ to SQL classes for two tables in my DB: Providers and Assignments. I added the following member to the Provider class:
public IEnumerable<Assignment> Assignments
{
get
{
return (new linqDataContext())
.Assignments
.Where(a => a.ProviderID == this.ProviderID);
}
}
Then, I bind a GridView using a query that pulls from the parent Provider and uses the child member Assignments, like this:
protected void PopulateProviders()
{
linqDataContext context = new linqDataContext();
var list = from p in context.Providers
where (p.Assignments.Count(a => a.Category == ddlCategory.SelectedValue) > 0)
select p;
lvProviders.DataSource = list;
lvProviders.DataBind();
}
At .DataBind(), when it actually runs the query, it throws the following error:
Member access 'System.String Category' of 'Namespace.Assignment' not legal on type 'System.Collections.Generic.IEnumerable`1[Namespace.Assignment].
I've tried checking for nulls (a => a != null && a.Category ...) but that hasn't worked. I'm not sure what to try next. I think that, if I knew what the error is trying to tell me, I could find the solution. As it stands, I don't know why member access would be illegal.
That Assignments property is all wrong. First of all, property getters should not have side-effects, and more importantly, entity classes should never have reverse dependencies on the DataContext. Linq to SQL has no way to decipher this query; it's relying on a property that does all sorts of crazy stuff that Linq to SQL can't hope to understand.
Get rid of that Assignments property now. Instead of doing that, you need to write this query as a join:
int category = (int)ddlCategory.SelectedValue;
var providers =
from p in context.Providers
join a in context.Assignments
on p.ProviderID equals a.ProviderID
into g
where g.Count(ga => ga.Category == category) > 0
select p;
That should do what you're trying to do if I understood the intent of your code correctly.
One last side note: You never dispose properly of the DataContext in any of your methods. You should wrap it like so:
using (var context = new linqDataContext())
{
// Get the data here
}
I think somewhere it doesn't know that type that is in the IEnumerable. You are trying to call a method that is not part of the IEnumerable inteface.
Why don't you just move the query from the property out to the PopulateProviders() method?
Remove your custom-defined Assignments property. In the your Linq-To-SQL dbml file, create an association between Providers and Assignments, with Providers as the parent property, and ProviderID as the Participating Property for both entities. LINQ will generate a property "IEnumerable Assignments" based on matches between ProviderID using a consistent DataContext.

Categories

Resources