Full object projection with additional values in LINQ - c#

Is it possible to project every property of an object and add more, without specifically listing them all. For instance, instead of doing this:
var projection = from e in context.entities
select new QuestionnaireVersionExtended
{
Id = e.Id,
Version = e.Version,
CreationDate = e.CreationDate,
...
many more properties
...
NumberOfItems = (e.Children.Count())
};
Can we do something like this:
var projection = from e in context.entities
select new QuestionnaireVersionExtended
{
e,
NumberOfItems = (e.Children.Count())
};
Where it will take every property from e with the same name, and add the "NumberOfItems" property onto that?

No this is not possible. The select clause of a LINQ expression allows for normal C# expressions which produce a value. There is no C# construct which will create an object via an object initializer in a template style manner like this. You'll need to either list the properties or use an explicit constructor.

If you add a constructor to QuestionnaireVersionExtended that takes your entity plus NumberOfItems, you can use the constructor directly:
var projection = from e in context.entities
select new QuestionnaireVersionExtended(e, NumberOfItems = (e.Children.Count()));
There is, however, no way to tell the compiler "just copy all of the properties across explicitly."

There are several ways that you could accomplish this but they all are going to be nightmares.
1.) Overload a constructor and copy all of the values there (however that is what you are trying to get away from.
2.) Use reflection to copy the properties over (many bad side effect, not recommended)
3.) USE THE DECORATOR PATTERN. It looks like you added values to the original class so I think this would be the perfect time to use a decorator. This would also make it so that as properties are added they aren't missed. It would break the compile, however this solution isn't perfect if the object being decorated is sealed.

Related

How to assign List<Parent> to List<Child> which is parent extended with 2 additional properties?

I'm making ASP.NET MVC app and i have class Order but i want to have 2 additional properties in it just for view. I figured out i will just make a class ViewOrder which derives from Order and has 2 additional properties so i could just assign Order object to OrderView and then set those 2 properties and pass this object to view.
Is it the proper way? When i was looking for answer on casting people were giving examples like "Cat inherits from mammal. You can't cast mammal to cat because it could be a dog" or something like that.
List:
var orderList = new List<Order>(_context.Orders)
Like that it doesn't even compile:
List<OrderView> orderViewList = (List<OrderView>)orderList;
This compile but throws "InvalidCastException":
var orderViewList = orderList.Cast<OrderView>().ToList();
Probably the simplest solution is to perform an explicit mapping operation:
List<Order> orderList = new List<Order>(_context.Orders);
List<OrderView> orderViewList = new List<OrderView>(); // Empty.
foreach (Order order in orderList)
{
OrderView orderView = new OrderView;
orderView.OrderNo = order.OrderNo;
orderView.CustomerId = order.CustomerId;
// ... etc
orderViewList.Add(orderView);
}
You cannot cast base class to derived class, there is no built-in method. You can either write a constructor OrderView(Order) that can do the conversion and use Linq to make it look clean.
// OrderView constructor
public OrderView(Order order)
{
this.OrderNo = order.OrderNo;
}
// Linq to create new list
List<OrderView> orderView = orders.Select(o => new OrderView(o));
Or use it this way, but not recommended
List<Order> orders = new List<OrderView>();
I must apologize for the previous answer. The problem lies here:
List<OrderView> orderViewList = (List<OrderView>)orderList; //<== Casting
The real truth is: Order is the parent of Orderview. So you cannot create a parent and assign it to a child. You can only create a child and assign it to a parent.
So, OrderView is another version of Order. But Order is not a version of OrderView.
Here's a thorough example:
when a child is assigned to a parent, any other features the parent doesn't have that the child has are ignored. But features that are required by a child, are required from a parent when that parent is assigned to a child. Which generates this casting issue.
I am not sure if what you're trying to do will serve you in the long run but there's probably a better approach of doing it. Please provide your Order class and identify what you specifically want to achieve with OrderView. Because the way I understand it, OrderView is supposed to be a method within Order provides a representation of Order you can simply create those extra fields you mentioned as private fields so that you can use them to create this OrderView() method.

Access a property of a DbSet by name

I have a DbSet<T>
I want to access one of the properties on it by name.
Is this possible?
I'm basically making a generic function, so that for any DbSet I have, I can specify a column and have it list the values of that column.
You can get the DbSet itself from the context by doing context.Set(T) but I am not sure about the fields.
I did something similar a while back using reflection.
T item = context.Set(T).First();
string propName = "MyProperty";
object value = item.GetType().GetProperty(propName).GetValue(item, null);
Of course note that you'll either need to cast the values to a specific type manually, or use ToString, which should work quite well on all basic types.
This assumes you already have the data from the server, and now need to process it.
EDIT:
If you want to create a query, then I found this!
Apparently, what you're looking for is available as part of Entity Framework these days.
An extension method is available which allows you to use .Select("propertyName") which returns IQueriable. Remember to add System.Linq.Dynamic to your using section.
You can then create select queries by specifying the name of the parameter.
List<object> data = (db.Set<SetType>()
.Where("propertyName == #0 && someOtherProperty == #1", propertyValue, someOtherPropertyValue)
.Select("propertyName") as IEnumerable<object>).ToList();
Check out this article on Dynamic LINQ.
Using the provided code, I was able to write a LINQ to Entities query like this:
var query = context.Set(Type.GetType("Person")).Select("Name");

How to create objects dynamically with C#?

I'm trying to create objects dynamically but I don't know how to. What I need is, I have a class for that object, and objects properties are stored in the database. Then I'll need to compare the properties of each object to get the desired result.
So I need to dynamically create objects on the fly with the properties loaded from database.
I don't think you need to create objects dynamically, just create one statically that matches your db schema with the property details, then you can compare the values of the properties across rows, or within an instance of your object.
I have been working on something similar to this. There are several things:
Include the System.Reflection namespace
Create an object dynamically using Activator
Get the object properties using the myObjectType.GetProperties() method
Here is an example of a generic object creation function using the above methods:
using System.Reflection;
public static Item CreateItem<Item>(object[] constructorArgs, object[] propertyVals)
{
//Get the object type
Type t = typeof(Item);
//Create object instance
Item myItem = (Item)Activator.CreateInstance(t, constructorArgs);
//Get and fill the properties
PropertyInfo[] pInfoArr = t.GetProperties();
for (int i = 0; i < pInfoArr.Length; ++i)
pInfo.SetValue(myItem, propertyVals[i], null); //The last argument is for indexed properties
return myItem;
}
Of course the above example assumes that the values in the property value array are arranged correctly, which is not necessarily the case, but you get the idea.
With the PropertyInfo class you can get properties, get property names, get attributes associated with the properties, etc. Powerful technology. You should be able to do what you need with the above info, but if not let me know and I will add more info.
If you have a number of objects you want to instantiate from database values it can be done something like this.
//database code goes here, results go in results
List<ClassName> l = new List<ClassName>()
foreach(Row r in results){
l.Add(new ClassName(){ClassProperty1 = r.Property1,ClassProperty2 = r.Property2});
}
Are you talking about Dictionary?
var dict=new Dictionary<string, string>();
dict.Add("property1", "val1");
dict.Add("property2", "val2");
var prop2val=dict["property2"];
Maybe Activator is what your looking for?
http://msdn.microsoft.com/en-us/library/system.activator.aspx
Check this class, compile in the realtime. But it's performance is not quite good.
http://msdn.microsoft.com/zh-cn/library/microsoft.csharp.csharpcodeprovider(VS.80).aspx
You could use reflection to dynamically build your objects:
Reflection msdn reference
I think that you want to retrieve rows from the DB and directly assign them to object given that the properties of the object are equivalent to the columns of DB table. If that what you mean then I believe you can't :)
Rob Conery did a small project called Massive that pretty much does what you're trying to accomplish. It's essentially a small ORM, in 400 lines of Dynamic C# 4.0 code.
Rob has been doing this kind of thing for quite some time with SubSonic, so you might find his approach with Massive quite interesting.
http://blog.wekeroad.com/helpy-stuff/and-i-shall-call-it-massive
Some of the code is explained here, with examples:
http://blog.wekeroad.com/microsoft/the-super-dynamic-massive-freakshow

LINQ to SQL Custom Property query on where clause

I am using LINQ to SQL classes, and have extended one (with a partial class) and added an extra property. I want to query on this property, so:
(from p in db.TableName where p.CustomProperty=="value" select p)
However this doesn't work. I get an error: The member 'TableName.CustomProperty' has no supported translation to SQL. At the moment I have no code in the 'set' section of my Custom Property as I'm unsure how.
So basically, Custom Property which can be queried on with LINQ to SQL, how?
As a follow up: this CustomProperty is NOT a column in the table. It is a separate value, but I need to both fetch it (easy enough) but also query on it!
As you can understand, there can't be any magic, so essentially there will be two queries: first one is a SQL query with database criteria and on its result there should be applied your custom criteria as a second query.
So the workaround you could use is to split two parts explicitly like this:
var dbFetch = (from p in db.TableName where p.RealProperty ==" value" select p).ToArray();
var result = from p in dbFetch where p.CustomProperty == "value" select p;
But of course you'll run into several limitations. For example if you fetching results page-by-page, the second criterion will break paging since it performs additional filtering.
HTH
It's called LINQ to SQL. Just to avoid misunderstandings.
About your problem: have you added that property using the designer? And have you re-created the database after that?
If you did it by hand, make sure you have a private storage field (like _CustomProperty), and your property (CustomProperty) is marked with the ColumnAttribute, e.g.
private string _CustomProperty;
[Column(Storage="_CustomProperty", CanBeNull=true)]
public string CustomProperty
{
get { return _CustomProperty; }
}
Hope this helps.
Aren't you missing an equality sign there? In C#, equality is expressed with double equal signs, as in "a == b", while single equal sign signifies assignment, as in "obj.SomeProp = 5;"
I have implemented a system where you can query manually added properties that represent enumerated wrappers around integer properties from database columns. So I know it's possible, and it looks like you might be wanting to do something similar. The way I did it was not easy, though, and unless you are building a framework that you want to use properly for many cases, you might be better off using the solution suggested by archimed7592. I don't have the code handy at the moment so I can't provide all the details, but briefly my solution works like this. I created a custom LINQ provider, replacing the LINQ-to-SQL provider. I did this by implementing a custom IQueryable interface that returned my LINQ provider instead of that provided by LINQ-to-SQL. Then, in the functions that take expression objects, I pre-processed the expression before returning the result. I replaced all comparisons between enum-type properties and enum values with comparisons between integer properties and integer values, then passed that expression to the normal LINQ-to-SQL implementation in order to return the result. Since expressions are read-only, I had to make a (recursive) function that re-built the entire expression with the customized parts replaced.

How should anonymous types be used in C#?

I've seen lots of descriptions how anonymous types work, but I'm not sure how they're really useful. What are some scenarios that anonymous types can be used to address in a well-designed program?
Anonymous types have nothing to do with the design of systems or even at the class level. They're a tool for developers to use when coding.
I don't even treat anonymous types as types per-se. I use them mainly as method-level anonymous tuples. If I query the database and then manipulate the results, I would rather create an anonymous type and use that rather than declare a whole new type that will never be used or known outside of the scope of my method.
For instance:
var query = from item in database.Items
// ...
select new { Id = item.Id, Name = item.Name };
return query.ToDictionary(item => item.Id, item => item.Name);
Nobody cares about `a, the anonymous type. It's there so you don't have to declare another class.
From LINQ in action (page 76 section 2.6.3):
... anonymous types [are] a great tool for quick and simple temporary results. We don't need to declare classes to hold temporary results thanks to temporary types.
basically they're useful to hold information in the local scope temporarily. Anything more requires the use of reflection and can become quite a problem. The example they give in the above-quoted book is in writing to console the id, name, and amount of memory taken up by each running process. They create an anonymous type, add it to a list (all one statement) and then use ObjectDumper to output it. Therefore the code no longer needs a separately declared class to hold the id, name and memory used but its all declared implicitly bringing the line count down to 4:
var pl = new List<Object>();
foreach(var p in Process.GetProcesses())
pl.Add(new {p.Id, p.ProcessName, Memory=p.WorkingSet64});
ObjectDumper.Write(pl);
The most popular use of anonymous types are for specifying projections in a LINQ to SQL query.
This query
from x in db.Table1 select new {x.Column1, Alias2=x.Column2}
will be converted to this SQL:
SELECT Column1, Column2 AS Alias2 FROM Table1
With anonymous types, you can create ad hoc projections without defining the type for it beforehand. The compiler will define the type for you.
When you create types for 'Use and throw' purposes.
This seems to have come due to LINQ. Seems to be a way to create structures with fields on the fly for a LINQ query. Returning a struct/type with specified fields only. If not for this, you'd have to declare a .Net type for each unique combination of fields you wish to retrieve.
Use them with Linq.
It is important to know, that LINQ doesn't force you, to use anonymous types. You can also write normal object constructions after select.
var query = from item in database.Items
// ...
select new Person(item.id, item.Name)
This prevents you from ugly reflection programming.
#Wouter :
var query = from item in database.Items
select new Person
{
ID =item.id,
NAME= item.Name
};
where ID and NAME are real property of your Person class.

Categories