Storing query result into a variable - c#

I'm a very beginner of C# and have some troubles with correct understading of generic types. In this example I would like to somehow store a query result into a variable.
The code I showed below is incorrect, because generic type T should specified.
public class Data
{
public IQueryable<T> Results { get; set; }
public Data()
{
var db = new Database();
}
public void Store()
{
Results = db.Products.Select(x => new { x.ProductName, x.Cost });
}
}
Is it possible to do it without declaring a special class for only one use, like this one?
public class ProductView
{
public string ProductName { get; set; }
public int Country { get; set; }
}
...
public IQueryable<ProductView > Results { get; set; }
Also, why dynamic type doesn't suit in this example?
public dynamic Results { get; set; }

There are 3 ways to solve this problem:
1) Create class like ProductView that you mentioned - classical C#6 or older way
2) Use dynamic instead of T like: public IQueryable<dynamic> Results { get; set; } - not recommended, because it increases risk of runtime errors and reduces readability
3) Use tuples (C#7 feature):
public IQueryable<(string, int)> Results { get; set; } // I suppose ProductName is string and Cost is int
public void Store()
{
Results = db.Products.Select(x => (x.ProductName, x.Cost));
}

The problem here is that your Data class appears to know some specific things about T. In the Store method it reads the Products and obtains two specific properties from each item. So it is not actually a generic class that can store any type. It's very specific.
To make it generic you would need to remove the Store method. And then there is not much left. You need to decide what the purpose of Data is. What problem does it exist to solve?

Related

C# Optimal way to get property from all class members of same type

I'm trying to shorten the code to most efficient way to access a specific property in all the members of the class.
public class Title
{
public string reference { get; set; }
public string root { get; set; }
public string name { get; set; }
public string description { get; set; }
public string shortT { get; set; }
}
public class Results
{
public List<Title> pop { get; set; }
public List<Title> exact { get; set; }
public List<Title> sub { get; set; }
...
}
Results is coming out of a JSON deserialize. It contains members of the same type, pop, exact and sub (the exact number of members could vary). I would like to filter all the objects in Results who's name contains "jackie"
So what would be the optimal/efficient way to iterate through the Lists of the members (pop, exact, sub) and look at the property name and see if it contains "jackie", without having to directly reference pop, exact or sub.
Reason being that the JSON could return more members tomorrow like pop or exact etc that I don't know in advanced, so I need to find a way to combine them all into a single searchable list (as they are all of the same type).
Consequently is a way to directly reference the property name for all the members in a single statement as in
foreach (string n in Results*.name)
you can make List of that classes and access with expression
List<Title> asdf = new List<Title>;
asdf.where(var => var.name == "jackie").ToList().ForEach(var =>
{
//do actions with this classes var.
};
Hope I help you ;)
You'll have to reference all three properties if you want to access what's in them. If you want to view the contents of all three as one collection you can Union them.
// given that r is an instance of Results
var combinedTitles = r.exact.Union(r.pop).Union(r.sub);
var matches = combinedTitles .Where(title => title.name == "title you want to match");

Return a List<SomeObject> without a certain property using Linq in c#?

I have an object containing different properties like the object below:
public class CompressedLogResponse
{
public string LoggerType { get; set; }
public int NumberOfRegisters { get; set; }
public int NewLogId { get; set; }
public DateTime LoggerAnnounceTime { get; set; }
public List<Log> Log{ get; set; }
}
How can I return a List of this objekt that does not include the List<Log> Log property?
Linq would be preffered
Thanks for any help that you can provide
You cannot just hide a property of a class (you declared it a as public)
Option 1:
Althought as Robson wrote you can set it null (thats not very reliable thaught cause nobody expects a class containing a property that is always null)
Option2:
If you consume the class on the same place use a anonymous type as Mez wrote, althought it sounds like you want to hide the Property from external usage. (I don't like the dynamic approach, the dynamic keyword was made for interop/DOM not for transporting anonymous types.)
Option3:
If you want a List of this type to be returned without the Log property, you have to create a new class (Inheritance is a good way to realize this):
public class CompressedLogResponseBase
{
public string LoggerType { get; set; }
public int NumberOfRegisters { get; set; }
public int NewLogId { get; set; }
public DateTime LoggerAnnounceTime { get; set; }
}
public class CompressedLogResponse : CompressedLogResponseBase
{
public List<Log> Log{ get; set; }
}
Now you can return a list of base items (that do not have a Log property at all)
public List<CompressedLogResponseBase> ReturnWithoutLog(IEnumerable<CompressedLogResponse> items)
{
return ((IEnumerable<CompressedLogResponseBase>)items).ToList();
}
If a IEnumerable as return type is suficient it becomes really easy
public IEnumerable<CompressedLogResponseBase> ReturnWithoutLog(IEnumerable<CompressedLogResponse> items)
{
return items
}
whith "does not include the List Log property" i guess you mean that the property "public List Log" will be blanked but still there, so you can just null that property out, because if you create an object that doesn't contain the "public List Log" property, than it will not be a "CompressedLogResponse" but will be another type.
List<CompressedLogResponse> listOne = new List<CompressedLogResponse>();
//....
//fill the listOne
//....
List<CompressedLogResponse> listWithoutListLog = (from item in listOne
select new CompressedLogResponse(
LoggerType = item.LoggerType,
NumberOfRegisters = item.NumberOfRegisters ,
NewLogId = item.NewLogId ,
LoggerAnnounceTime = item.LoggerAnnounceTime ,
Log= null)).ToList();
You can return an anonymous list of your original list like the following;
public static List<dynamic> Test() {
List<CompressedLogResponse> list = new List<CompressedLogResponse>();
var result = list.Select(x => new
{
x.LoggerAnnounceTime,
x.LoggerType,
x.NewLogId,
x.NumberOfRegisters
});
return result.ToList<dynamic>();
}
Take a look at the .Select(), and also the dynamic keyword.
Then to call it,
var x = Test();
foreach(dynamic o in x)
{
int NumberOfRegisters;
//You have 2 ways... either by
NumberOfRegisters = o.NumberOfRegisters;
// or reflection
NumberOfRegisters = o.GetType().GetProperty("NumberOfRegisters").GetValue(o, null);
}

Facade a class without writing lots of boilerplate code?

Let's say I have a class from a 3rd-party, which is a data-model. It has perhaps 100 properties (some with public setters and getters, others with public getters but private setters). Let's call this class ContosoEmployeeModel
I want to facade this class with an interface (INavigationItem, which has Name and DBID properties) to allow it to be used in my application (it's a PowerShell provider, but that's not important right now). However, it also needs to be usable as a ContosoEmployeeModel.
My initial implementation looked like this:
public class ContosoEmployeeModel
{
// Note this class is not under my control. I'm supplied
// an instance of it that I have to work with.
public DateTime EmployeeDateOfBirth { get; set; }
// and 99 other properties.
}
public class FacadedEmployeeModel : ContosoEmployeeModel, INavigationItem
{
private ContosoEmployeeModel model;
public FacadedEmployeeModel(ContosoEmployeeModel model)
{
this.model = model;
}
// INavigationItem properties
string INavigationItem.Name { get; set;}
int INavigationItem.DBID { get; set;}
// ContosoEmployeeModel properties
public DateTime EmployeeDateOfBirth
{
get { return this.model.EmployeeDateOfBirth; }
set { this.model.EmployeeDateOfBirth = value; }
}
// And now write 99 more properties that look like this :-(
}
However, it's clear that this will involve writing a huge amount of boilerplate code to expose all the properties , and I'd rather avoid this if I can. I can T4 code-generate this code in a partial class, and will do if there aren't any better ideas, but I though I'd ask here to see if anyone had any better ideas using some super wizzy bit of C# magic
Please note - the API I use to obtain the ContosoEmployeeModel can only return a ContosoEmployeeModel - I can't extend it to return a FacededEmployeeModel, so wrapping the model is the only solution I can think of - I'm happy to be corrected though :)
The other approach may be suitable for you is to use AutoMapper to map base class to your facade here is sample code:
class Program
{
static void Main(string[] args)
{
var model = new Model { Count = 123, Date = DateTime.Now, Name = "Some name" };
Mapper.CreateMap<Model, FacadeForModel>();
var mappedObject = AutoMapper.Mapper.Map<FacadeForModel>(model);
Console.WriteLine(mappedObject);
Console.ReadLine();
}
class Model
{
public string Name { get; set; }
public DateTime Date { get; set; }
public int Count { get; set; }
}
interface INavigationItem
{
int Id { get; set; }
string OtherProp { get; set; }
}
class FacadeForModel : Model, INavigationItem
{
public int Id { get; set; }
public string OtherProp { get; set; }
}
}
Resharper allows the creation of "delegating members", which copies the interface of a contained object onto the containing object and tunnels the method calls/property access through to the contained object.
http://www.jetbrains.com/resharper/webhelp/Code_Generation__Delegating_Members.html
Once you've done that, you can then extract an interface on your proxy class.

Cloning A Class

I have two classes which contain the same fields, however one inherits some properties from somewhere else and the other does not.
I have created a generic list using the class "ZEUS_ResearchStocksHistory" , but then I need to clone all of the fields over to the other list "ZEUS_ResearchStocksHistoryWithExcel". I don't want to have to loop through each field in one list and populate the other, or write some sort of linq join, there must be a faster way?
The reason I can't use the same class in both instances is that when inheriting the ExcelReport function it adds additional fields which I do not want when I display this list in a data grid.
internal class ZEUS_ResearchStocksHistory
{
public String Amendment { get; set; }
public String AmendedBy { get; set; }
public String Sedol { get; set; }
public String Date { get; set; }
}
internal class ZEUS_ResearchStocksHistoryWithExcel : ExcelReport
{
public String Amendment { get; set; }
public String AmendedBy { get; set; }
public String Sedol { get; set; }
public String Date { get; set; }
}
Is this possible?
Thanks
Did you have a look at automapper?
example from codeproject:
CustomerViewItem customerViewItem =
Mapper.Map<Customer, CustomerViewItem>(customer);
Check out Automapper, which is designed to do exactly this. Automapper is up on NuGet.
http://lostechies.com/jimmybogard/2009/01/23/automapper-the-object-object-mapper/
You could do something as simple as:
Mapper.CreateMap<ZEUS_ResearchStocksHistory, ZEUS_ResearchStocksHistoryWithExcel>();
var newObject = Mapper.Map<ZEUS_ResearchStocksHistory, ZEUS_ResearchStocksHistoryWithExcel>(oldObject);
Or, since you said you have a list, you could do:
var newList = oldList.Select(x => Mapper.Map<ZEUS_ResearchStocksHistory, ZEUS_ResearchStocksHistoryWithExcel>(x));

Help refactor my C# code to be more maintainable and to use best coding practices

I have this C# class structure that I would like to refactor to use best coding standards (use interfaces/abstract classes) so it can be more maintainable and reusable. The code as it is right now isn't awful, but it's not ideal.
I have a series of TableItemGroup classes: AccountTableItemGroup, PendingVoteTableItemGroup, and RequestingVoteTableItemGroup. Each TableItemGrup contains a string SectionName and a List for its corresponding TableItem ...as such:
public class AccountTableItemGroup {
public string SectionName { get; set; }
public List<AccountTableItem> Items
{
get { return this._items; }
set { this._items = value; }
}
public List<AccountTableItem> _items = new List<AccountTableItem>();
public AccountTableItemGroup()
{
}
}
In the future there will be many more TableItemGroups and if they are all the same except for the List part, I don't want to have to copy the code and create a new Group every time and make that small change. I know there must be a better way. I would like to keep using the List<> generics so I don't have to cast anything later though.
The other part are the TableItems. I have AccountTableItem, PendingVoteTableItem, and RequestingVoteTableItem. The TableItems are different from each other, but they each share three common strings -- TitleLabel, DetailLabel, and ImageName. But after that, each TableItem may or may not have additional properties or methods along with it ..as such:
public class AccountTableItem
{
public string TitleLabel { get; set; }
public string DetailLabel { get; set; }
public string ImageName { get; set; }
public bool SwitchSetting { get; set; }
public AccountTableItem()
{
}
}
So my question to all of you is, how do I redefine my class structure to allow for as much reuse of code as possible and to use best coding standards?
I was thinking of having an abstract TableItem class or use an interface for the TableItemGroup? I know that using an interface or an abstract class is best for coding standards, but I don't see how it would cut down on the amount of code I will have?
Thanks a lot for any help.
Abstract away your table item adding necessary fields to the interface or base class:
interface ITableItem // or just a simple or abstract class
{
// common fields go here
}
Then can you make your item group generic with a constraint on generic parameter.
public class ItemGroup<T> where T: ITableItem
{
public string SectionName { get; set; }
public List<T> Items { get; private set; }
public ItemGroup()
{
Items = new List<T>();
}
}
Consider using generics to represent the TableItemGroup container, and make a base class for your TableItem, which you can inherit from for specific types of table item. If you inherit directly from List<T>, then you can treat your item group as a collection without having to use the Items property as in your existing design.
There's not much point in using interfaces for these sorts of types. As they stand they are data classes so have no behavior. If they had behavior, using interfaces would make sense as you would then be able to change implementations and so vary behavior.
public class TableItemGroup<T> : List<T> where T : TableItem
{
public TableItemGroup(string sectionName)
{
SectionName = sectionName;
}
public string SectionName { get; private set; }
}
public class TableItem
{
public string TitleLabel { get; set; }
public string DetailLabel { get; set; }
public string ImageName { get; set; }
}
public class AccountTableItem : TableItem
{
public bool SwitchSetting { get; set; }
}
Now that we have a generic TableItemGroup container, you can re-use this for all TableItem types. Having a base class for TableItem again gives you some re-use.
var items = new TableItemGroup<AccountTableItem>("Accounts");
items.Add(new AccountTableItem { SwitchSetting = true });
Unless you want users to be able to add and remove new lists at will, you should make the setter on the items list protected. Users will still be able to add and remove items, but not create a reference to a new list.

Categories

Resources