Is IEnumerable<object> the proper container for generic data sets? - entity-framework

Using Entity Framework, is IEnumerable the correct container to use to send back a generic data set? I.e. when I do not want to send back a list of the object, but just a generic a result set.
public IEnumerable<object> SelectPlayerFirstAndLastNameList()
{
return (from p in rlpEntities.Players select new { p.PlayerFirstName, p.PlayerLastName });
}
Thanks.

Here is the reference article, which talks about IList(inherits ICollection( and IEnumerable(Base Generic Interface for IQueryable,ICollection,List).
Here are the links which states generics & it's differences & it's usages,
Difference among IEnumerable , IQueryable, ICollection,IList, List
IEnumerable vs. ICollection vs. IQueryable vs. IList
Looking at your linq, it's about specific object & can be extended further in future. IQueryable is right fit for such scenario, as it gives client to iterate/add/remove items.

Check this link out Why use ICollection and not IEnumerable or List<T> on many-many/one-many relationships?.
It really depends on your scenario, but IEnumerable<> would be used when you need to iterate, and List<> when you need to iterate and modify or sort the data.
IEnunerable<> - http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx
List<> - http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx
You can also use generics, to pass on whatever types you are querying against, like for instance
public IEnumerable<T> SelectPlayerFirstAndLastNameList<T>()
{
return (IEnumerable<T>)(from p in rlpEntities.Players);
}
So you can pass either object, or a known defined type. To call this you would do
var x = SelectPlayerFirstAndLastNameList<YourClassHere>();

I think what you have is correct but decide for yourself whether you should use it.
From MSDN: Anonymous Types in the Remarks section:
Anonymous types are class types that derive directly from object, and
that cannot be cast to any type except object.
and
To pass an anonymous type, or a collection that contains anonymous
types, as an argument to a method, you can declare the parameter as
type object. However, doing this defeats the purpose of strong typing.
If you must store query results or pass them outside the method
boundary, consider using an ordinary named struct or class instead of
an anonymous type.

Related

Java: help understanding the use of interfaces as a data type?

I am having trouble understanding with some of the code snippets about this part of the Java tutorial: http://docs.oracle.com/javase/tutorial/java/IandI/interfaceAsType.html
public Object findLargest(Object object1, Object object2) {
Relatable obj1 = (Relatable)object1;
Relatable obj2 = (Relatable)object2;
if ((obj1).isLargerThan(obj2) > 0)
return object1;
else
return object2;
}
and:
public interface Relatable {
// this (object calling isLargerThan)
// and other must be instances of
// the same class returns 1, 0, -1
// if this is greater than,
// equal to, or less than other
public int isLargerThan(Relatable other);
}
In the first example, why am I downcasting Object types into Relatable types? What happens if the first method doesn't include the first two statements?
Let's say I wrote a Rectangle class that implements the Relatable interface and has the "findLargest" method. If I know that I'm comparing two Rectangle objects, why not just make the first method downcast the objects into Rectangles instead?
You cast the Objects into Relatable types because otherwise you cannot use the methods declared in the Relatable interface. Since Object does not have the isLargerThan method, you would get a compiler error without casting. Honestly, in my opinion the findLargest method as shown here was not very well designed; a better illustration of the purpose of Interfaces would be to ask for Relatable objects as the parameters like so:
public Object findLargest(Relatable object1, Relatable object2) {
//implementation not shown to save space
}
This way, the user must pass Relatable objects, but they can pass any object whose class implements Relatable (such as Rectangle)
"If I know that I'm comparing two Rectangle objects..."True, if you know that you are comparing two Rectangle objects, there is little use for an interface, but the purpose of interfaces is to allow you to create a generic "type" of object that can be used to define common features of several different classes.For example, what if you also had a Circle class and a Square class (both of which implemented Relatable)? In this case, you do not necessarily know the exact type of object you have, but you would know that it is Relatable, so it would be best to cast to type Relatable and use the isLargerThan method in a case like this.
Interfaces define a set of methods which every class which the interface implements has to implement. The downcast is necessary to get access to these methods.
You don't know if you are comparing rectangles with this interface. You could get any Relatble passed. This is one of the cases generics come in handy.
1.In the first example, why am I down casting Object types into Relatable types? What happens if the first method doesn't include the first two statements?
Answer
Every object has some basic functionality and you want a specific object write now. You are down casting your object into a "Relatable" so you can use the "isLargerThan" method(an object wont have it since it has only basic common stuff).
If you didn't down cast, you would not pass compilation.
2.Let's say I wrote a Rectangle class that implements the Relatable interface and has the "findLargest" method. If I know that I'm comparing two Rectangle objects, why not just make the first method downcast the objects into Rectangles instead?
Answer
Since you want to create something generic.
Lets say you have a Student and a Driver. Both of them are People. You can create an interface called IPeople and make both the Student and the driver implement it.
IPeople will have a method called "getAge()" that each of them will implement.
IPeople will have all the functionality that you need for "People". That's how you create cross object functionality under the "same hat".

Why isn't DbSet covariant?

I have a factory function to return a DbSet(Of IItemType). The actual return type will always be an implementation IItemType, for example DbSet(Of CategoryType).
I thought covariance is supported in generics and this method would work fine, but I get an exception when I try to run my code:
Unable to cast object of type 'System.Data.Entity.DbSet1[CategoryType]' to type 'System.Data.Entity.DbSet1[IItemType]'.
DbSet<T> CANNOT be co-variant. Firstly, this is because in C#, classes cannot be co-variant...only interfaces. Secondly because DbSet<T> has both co-variant and contra-variant methods.
Take the following two examples.
DbSet<CategoryType> set = context.Set<CategoryType>();
IQueryable<IItemType> query = set.Where(x => x.Foo == Bar);
So we know for a fact that all CategoryTypes are IItemType, so we know this can always work.
However conversely try this...
DbSet<CategoryType> set = context.Set<CategoryType>();
IItemType newItemType = new ProductType();
set.Add(newItemType); // Compiler error.
Not all IItemTypes are CategoryType. So if we could cast DbSet<CategoryType> to DbSet<IItemType> we would get run time errors when adding... Since the compiler knows that this might not always work, it won't let you do the casting.
However there are interfaces that DbSet<T> does allow Co-Variance on. You can try casting it to IQueryable<IItemType> for example.
However it sounds like you are trying to query against the DbSet using a query against the interface... try the following
DbSet<CategoryType> set = context.Set<CategoryType>();
IQueryable<IItemType> cast = set.OfType<IITemType>(); //(or .Cast<>() works too)
IQueryable<IItemType> query = cast.Where(x => x ....);
It looks like they could be covariant. But there is a host of differences between in-memory programming and programming against a query provider.
For Entity Framework to materialize an object from the data store it requires its exact type and the mapping from database columns to the type's properties. An interface can represent any type and EF is not (yet) able to pick a suitable implementation itself. Maybe support for interfaces will be featured in future releases.
The same applies to casting entities to an interface in an EF query (a case I just added to my list of differences).

GWT serialization should not return interfaces: what about parameters and contained objects?

There are already a few questions regarding the fact that methods in GWT RPC should not return an interface like List, but rather a concrete class like ArrayList, because otherwise "GWT needs to include all possible implementations". See e.g. In GWT, why shouldn't a method return an interface?
Here's my question: is this limited to the return type itself? How about parameters of the method? And what if the return object contains an interface, e.g.
public class MyReturnObject implements IsSerializable {
List<String> listOfUnspecifiedType1;
List<Long> listOfUnspecifiedType2;
...
}
The examples I have seen all talk of the return type itself. I don't see why it would be a problem to return an interface, but not a problem to return an object which just wraps an interface; but maybe I am missing something?
It's clear from the linked question that it applies recursively (and as soon as you understand why you should use the most derived types as possible, it becomes obvious that it is recursive).
This is also true of method arguments, not only the return types and their fields: if you send a List<X> then GWT has to generate serialization code for all List classes: ArrayList, LinkedList, etc.
And of course the same applies to classes, not only interfaces: AbstractList is no different from List.
And because generation comes before optimization, all possible classes from the source path will be included, not only those that you use in your code; and then they come in the way of the optimization pass, as all those classes are now used by your app.
Therefore, the rule is: use the most specific types as possible. The corollary is: don't fear DTOs, don't try to send your business/domain objects at all cost.

Enumerators, iterators, IEnumerable - a bit confused

I've read through the Iterators/Enumerators section of C# 3.0 in a Nutshell several times, but I'm still having a hard time grasping it. From their names, my initial thought is that an Iterator would iterate over a group of Enumerable objects. Am I on the right track? If so, then what about common generic collections, like a List<T>? Does List create/make use of an Iterator during some of its operations? Is T automatically Enumerable? Is there a cast? Does one even have anything to do with the other?
On a somewhat related note, while learning MVC, I've seen code like so:
public Article GetArticle(int id)
{
return _siteDB.Articles.SingleOrDefault(a => a.ArticleID == id);
}
public IEnumerable<Article> GetArticle(string title)
{
return _siteDB.Articles.Where(a => a.Title.StartsWith(title)).AsEnumerable<Article>();
}
What does having a return type of IEnumerable<T> give me?
EDIT: Okay, I think I'm beginning to get it. My confusion remains with Iterators. The book describes them as producers of Enumerators. I don't see where that actually happens with yield return. Does each yield create a new Enumerator?
The type IEnumerable gives you IEnumerable :)
It is an interface defining method GetEnumerator(), which returns IEnumerator. You can call the method as many times as you like and you always obtain new instance of IEnumerator.
The IEnumerator have property Current and methods MoveNext() and Reset() allowing the collection enumeration. The enumeration itself can be done by calling MoveNext() and reading the Current property if previous call of MoveNext() returns true.
Good example of implementation and usage is in documentation: http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.aspx
From their names, my initial thought is that an Iterator would iterate over a group of Enumerable objects. Am I on the right track? If so, then what about common generic collections, like a List? Does List create/make use of an Iterator during some of its operations?
An iterator is a way to implement a method returning an IEnumerable<T> - it's really an implementation detail. Instead of having to create some custom class to enumerate through a collection, you can use an iterator to implement it, and the compiler does the hard work for you.
What does having a return type of IEnumerable give me?
This basically allows you to enumerate over the type. For example, the second method (which I would personally call GetArticles), would allow you to write:
foreach(var article in GetArticle(theTitle))
{
// Do something with article
}
Lets see if I can answer this.
So a List implements IEnumerable, and its not the T that has to implement it, anything in a list can be iterated, using a forech or for loop, for example. If you use a generic list like List, this means that what you have is a list of T where T is the object type defined by you, that means you don't have to cast it, but in the other hand you can only put objects of that same type in that list.
The code you have up there, can mean a series of thing:
1 - Any variable that implements IEnumerable will be able to hold the result of GetArticle,
Ex:
List yourList = GetArticle("test");
Queue myQueue = GetArticle("test");
2 - The actual processing of the query will be delayed. If you call Count for example, after you call the method, thats when it actually get executed/resolved.
3 - Because of number 2, if you are doing that on a DB as the code suggests, then you connection has to remain open till the time where you make use of the list, otherwise you will get an exception.
I think I have answered the questions.

Serializing data using IEnumerable<T> with WebGet

possible duplicate:
Cannot serialize parameter of type ‘System.Linq.Enumerable… ’ when using WCF, LINQ, JSON
Hi,
If my method signiature looks like this, it works fine.
[WebGet]
MyClass[] WebMethod()
If the signiature looks like this
[WebGet]
IEnumerable<T> WebMethod()
I get the following error:
Cannot serialize parameter of type 'X.Y.Z.T+<WebMethod>d__2c' (for operation 'WebMethod', contract 'IService') because it is not the exact type 'System.Collections.Generic.IEnumerable`1[X.Y.Z.T]' in the method signature and is not in the known types collection. In order to serialize the parameter, add the type to the known types collection for the operation using ServiceKnownTypeAttribute.
I have tried adding.
ServiceKnownType(typeof(IEnumerable))
Same error.
Is this a bug in 2010 beta 2, or is this likely to be correct going forward?
Thanks
The iterator types generated by the C# compiler are not serializable and never will be.
If you read this page, you'll see that it wouldn't make sense to serialize the iterator.
You need to return an array.
EDIT: The simplest way to do that is to move your iterator to a seperate method, and change WebMethod to
[WebGet]
MyClass[] WebMethod() { return OtherMethod().ToArray(); }
I've run into the same issue, and in my case it's simply not possible to change my entire object graph from iterator-based IEnumerable to concrete types. I simply cannot afford the memory to convert over to concrete types like List or Array. Additionally, what about the case where I return an IEnumerable of some object that has an IEnumerable property. It is unacceptable that I have to recurse my entire object graph converting all IEnumerables.
I don't see any good reason why the DataContractSerializer can't iterate any IEnumerable type and render its elements to XML in the same manner as any other collection type, even if the IEnumerable doesn't have a concrete backing type.
This is a bug which should be fixed.