Fail to iterate through collection returned - linq

I have following program that fetches the data from DB and sends it to Main. I am able to iterate through the result in the function but not in Main.
Program is below :
void Main()
{
var data = GetAllCountry();
// foreach( var t in data)
// {
// Console.WriteLine("{0}", t.country.ID); //fails here; says country not found
// }
}
// Define other methods and classes here
public IEnumerable GetAllCountry()
{
var countries = COUNTRY.Select(c => new
{
country = new
{
ID = c.ID,
Description = c.DESCRIPTION,
CountryPhoneCode = c.COUNTRY_PHONE_CODE,
Currency = c.CURRENCY.CURRENCY_SYMBOL,
}
});
foreach( var t in countries)
{
Console.WriteLine("{0}", t.country.ID);//works here and I am able to access t.country.ID here...
}
return countries;
}
What wrong with this ? what are required modifications ?

I believe as you are returning IEnumerable rather than IEnumerable<T>, it is not able to get the object type.
If you create a class for Country and the method returns IEnumerable<Country> it would work
public IEnumerable<Country> GetAllCountry()
{
var countries = COUNTRY.Select(c => new
{
country = new Country
{
ID = c.ID,
Description = c.DESCRIPTION,
CountryPhoneCode = c.COUNTRY_PHONE_CODE,
Currency = c.CURRENCY.CURRENCY_SYMBOL,
}
});
foreach( var t in countries)
{
Console.WriteLine("{0}", t.country.ID);//works here and I am able to access t.country.ID here...
}
return countries;
}

Related

Cannot implicitly convert type 'string' to 'int' in class

I m trying to run below code and getting error can not implicitly convert string to int CS0029
on code new Customer { Name ="Cust one"} ,
new Customer { Name = "Customer2" }
find below full code
public ActionResult Random() // Random is action result or object name to be made any action
{
var customers = new List<Customer>
{
new Customer { Name ="Cust one"} ,
new Customer { Name = "Customer2" }
};
var viewModel = new RandomMovieViewModel
{
Movie = movie,
Customers = customers
};

Get List Data of selected Column from Table

I want to get data of selected columns from a table and return that data in repository class. But my query does not return any data.
My Code is:
public IQueryable<BusinessProfile> GetBusinessProfileAddress()
{
var y = _db.Set<BusinessProfile>().Where(x => x.Deleted == false).Select(x => new
{
x.ID,
x.Address.StreetName,
x.Address.Number,
x.Address.Complement,
x.Address.PostalCode,
x.Address.Neighborhood,
x.Address.City,
x.Address.State
});
var d=from a in BusinessProfile select a.
return y; ;
}
Note: Here "return y" is in showing error.
This code won't even build because you haven't finished this query: var d=from a in BusinessProfile select a., but, you are not using the d variable at all so you should remove the whole var d=from a in BusinessProfile select a. line. And you don't need 2 semicolons after y. So, your code should look like this:
public IQueryable GetBusinessProfileAddress() {
var y = _db.Set<BusinessProfile>().Where(x => x.Deleted == false).Select(x => new
{
x.ID,
x.Address.StreetName,
x.Address.Number,
x.Address.Complement,
x.Address.PostalCode,
x.Address.Neighborhood,
x.Address.City,
x.Address.State
});
return y;
}
For your current code, you will get error like
Cannot implicitly convert type 'System.Linq.IQueryable<>' to 'System.Linq.IQueryable'. An explicit conversion exists
If you want to return the new type, you may consider define a new model and change BusinessProfile.
public IQueryable<BusinessProfileVM> GetBusinessProfileAddress()
{
var y = _appDbContext.Set<BusinessProfile>().Where(x => x.Deleted == false).Select(x => new BusinessProfileVM
{
Id = x.Id,
StreetName = x.Address.StreetName,
});
return y;
}
public class BusinessProfileVM
{
public int Id { get; set; }
public string StreetName { get; set; }
}

how to convert parameterless constructor to MemberInitExpression

Can I create a MemberInitExpression or any expression of a parameterless constructor from a function that literally returns a parameterless constructor?
public IQueryable<GroupView> GetViewSelect(IQueryable<ItemGroup> myQ)
{
return myQ.SelectMany(GetExpression1(), GetExpression2());
}
internal static Expression<Func<ItemGroup, IEnumerable<ItemDetail>>>
GetExpression1()
{
// m is the ItemGroup
// m.item is Item
// m.item.itemDetail is a collection of ItemDetail
return m => m.item.itemDetail;
}
internal static Expression<Func<ItemGroup, ItemDetail, GroupView>>
GetExpression2()
{
// m is the ItemGroup
// n is the ItemDetail
// and it's error at runtime coz LINQ doesnt know the GetGroupView.. :(
return (m, n) => GetGroupView(m, n);
}
internal static GroupView GetGroupView(ItemGroup m, ItemDetail n)
{
// I think the same error will occurs
// coz LINQ doesnt know the GetItemView and GetItemDetailView
return new GroupView
{
Id = m.id,
Name = m.name,
ItemDetailsTotalCount =
m.item.ItemDetails.Sum(nn => nn.item.itemDetails.Count),
Item = GetItemView(m.item),
ItemDetail = GetItemDetailView(n)
};
}
internal static ItemView GetItemView(Item m)
{
return new ItemView
{
Id = m.id,
Name = m.name,
DetailCount = m.ItemDetail.Count
};
}
internal static ItemDetailView GetItemDetailView(ItemDetail n)
{
return new ItemDetailView
{
Id = n.id,
Name = n.name,
Supplier = GetSupplierView(n.supplier)
};
}
internal static SupplierView GetSupplierView(Supplier n)
{
return new SupplierView
{
Id = n.id,
Name = n.name,
Email = n.email ?? "no email",
Phone = n.phone ?? "no phone"
};
}
Of course none of those above works,.. but I just want to avoid retyping the same parameterless constructor over and over in order to get the view constructor every time I want to get different view..
For example, I'd like to call it like this
public IQueryable<ItemView> GetViewSelect(IQueryable<Item> myQ)
{
return myQ.Select(GetExpression3());
}
public IQueryable<ItemView> GetViewSelect(IQueryable<ItemDetail> myQ)
{
return myQ.Select(GetExpression3());
}
internal static Expression<Func<Item, ItemView>> GetExpression3()
{
return m => GetItemView(m);
}
internal static Expression<Func<ItemDetail, ItemView>> GetExpression4()
{
return m => GetItemView(m.item);
}
instead of writing the same parameterless constructor everytime I call it like this below..
internal static Expression<Func<Item, ItemView>> GetExpression3()
{
// writing same parameterless constructor again
return m => new ItemView
{
Id = m.id,
Name = m.name,
DetailCount = m.ItemDetail.Count
};
}
internal static Expression<Func<ItemDetail, ItemView>> GetExpression4()
{
// the same thing again
return m => new ItemView
{
Id = m.item.id,
Name = m.item.name,
DetailCount = m.item.ItemDetail.Count
};
}
internal static Expression<Func<ItemGroup, ItemDetail, GroupView>>
GetExpression2()
{
return (m, n) => new GroupView
{
Id = m.id,
Name = m.name,
ItemDetailsTotalCount =
m.item.ItemDetails.Sum(nn => nn.item.itemDetails.Count),
Item = new ItemView
{
Id = m.item.id,
Name = m.item.name,
DetailCount = m.item.ItemDetail.Count
},
ItemDetail = new ItemDetailView
{
Id = n.id,
Name = n.name,
Supplier = new SupplierView
{
Id = n.id,
Name = n.name,
Email = n.email ?? "no email",
Phone = n.phone ?? "no phone"
}
}
};
}
So I was actually looking for a way to convert
new ItemView
{
Id = m.id,
Name = m.name,
DetailCount = m.ItemDetail.Count
}
into a MemberInitExpression parameterless constructor so maybe I can use it like below without doing any member-assignment..
internal Expression<Func<Item, ItemView>> GetExpression4e
(ParameterExpression m)
{
// looking for something like this..
MemberInitExpression ItemViewInitExpression =
Something("GetItemView", new Object[] {m});
return Expression.Lambda<Func<Item, ItemView>>
(ItemViewInitExpression, m);
}
internal static Expression<Func<Item, ItemView>> GetExpression3()
{
// writing same parameterless constructor again
return m => new ItemView
{
Id = m.id,
Name = m.name,
DetailCount = m.ItemDetail.Count
};
}
This method already produces a MemberInitExpression. If you do
var type = GetExpression3().Body.GetType();
You'll get System.Linq.Expressions.MemberInitExpression
If all you want is to pass some parameters, then pass some parameters:
internal static Expression<Func<Item, ItemView>> GetExpression3(int id, string name, int count)
{
// writing same parameterless constructor again
return m => new ItemView
{
Id = id,
Name = name,
DetailCount = count
};
}

Re-using code in controller class

The following code is taken from the tutorial: http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/cs/examining-the-edit-methods-and-edit-view which shows how ASP.net MVC 3 can be used to manage a movie database.
In the tutoral, a list object is added to the controller class that contains every movie genre that exists in the database. This list is then passed to a drop-down in the view enabling the database to be searched by genre.
Controller: (code related to movie genre in bold)
public ActionResult SearchIndex(string movieGenre, string searchString)
{
var GenreLst = new List<string>();
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
GenreLst.AddRange(GenreQry.Distinct());
ViewBag.movieGenre = new SelectList(GenreLst);
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
if (string.IsNullOrEmpty(movieGenre))
return View(movies);
else
{
return View(movies.Where(x => x.Genre == movieGenre));
}
}
What I want to do is enhance this further so that the movies can be searched by price as well as genre. I know I can re-use the much of the same code to do this. I think I need to create a new class that the controller class can pass either the genre or price. Is this correct? IF so, I'd appreciate an example. Thanks.
Update/Clarification:
I want to avoid repeating the code for both genre and price as below:
public ActionResult SearchIndex(string movieGenre, string searchString,float moviePrice)
{
var GenreLst = new List<string>();
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
GenreLst.AddRange(GenreQry.Distinct());
ViewBag.movieGenre = new SelectList(GenreLst);
var PriceLst = new List<string>();
var PriceQry = from d in db.Movies
orderby d.Genre
select d.Genre;
PriceLst.AddRange(GenreQry.Distinct());
ViewBag.moviePrice = new SelectList(PriceLst);
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
if (string.IsNullOrEmpty(movieGenre))
return View(movies);
else
{
return View(movies.Where(x => x.Genre == movieGenre));
}
if (string.IsNullOrEmpty(moviePrice))
return View(movies);
else
{
return View(movies.Where(x => x.Genre == moviePrice));
}
}
You just have to insert a text box in the view to get price value. Then receive this value at action and modify the query to get desired results.
like this:
#Html.ActionLink("Create New", "Create")
#using (Html.BeginForm()){
<p>Genre: #Html.DropDownList("movieGenre", "All")
Title: #Html.TextBox("SearchString")
Price: #Html.TextBox("Price")
<input type="submit" value="Filter" /></p>
}
And in the action method you are using the code below to populate the dropdownlist with genre values. You need not do the same for price value.
var GenreLst = new List<string>();
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
GenreLst.AddRange(GenreQry.Distinct());
ViewBag.movieGenre = new SelectList(GenreLst);
And in your action method you just have to use the value of price to filter data
public ActionResult SearchIndex(string movieGenre, string searchString,float price)
{
var GenreLst = new List<string>();
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
GenreLst.AddRange(GenreQry.Distinct());
ViewBag.movieGenre = new SelectList(GenreLst);
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
if (string.IsNullOrEmpty(movieGenre))
return View(movies);
else
{
return View(movies.Where((x => x.Genre == movieGenre) &&(x => x.Price== price)));
}
}
You can do it in so many different ways while all are correct but it depends on the complexity of your project. Basically you don't want to over-engineer a simple program. But in general you should move all of your logic to a separate class and use your actions for creating and calling the right logic class:
public class GetMoviesRequest
{
public string Name { get; set; }
public float? Price { get; set; }
}
public class MoviesLogic
{
private List<Movie> Movies;
public IEnumerable<Movie> Get(GetMoviesRequest request)
{
IEnumerable<Movie> filtered = Movies.AsQueryable();
if (!string.IsNullOrEmpty(request.Name))
{
//Filter by name
filtered = filtered.Where(m => m.Name == request.Name);
}
if (request.Price.HasValue)
{
//Filter by value
filtered = filtered.Where(m => m.Price == request.Price);
}
return filtered;
}
}
public class MyController
{
public ActionResult SearchIndex(string movieGenre, string searchString)
{
var logic = new MoviesLogic();
var movies = logic.Get(new GetMoviesRequest() { Name = searchString } )
///do stuff with movies
}
}

EmitMapper and List

It's the first time that I use EmitMapper.
I have a list of object ex: Customer and I would like to map this list in a ienumerable of CustomerDTO how can I do that?
Tnx
It's straightforward if you have a list and want to convert it to list of DTOs:
var mapper = ObjectMapperManager.DefaultInstance.GetMapper<Customer, CustomerDTO>();
IEnumerable<CustomerDTO> dtos = listOfCustomer.Select(mapper.map);
The preblem is when the list is in another object, for example User and UserDTO:
class User {
public List<Customer> Customers { get; set; }
}
class UserDTO {
public IEnumerable<CustomerDTO> Customers { get; set; }
}
It seems that EmitMapper does not support conversion from List to Enumerable. A way to support it would be:
var customerMapper = ObjectMapperManager
.DefaultInstance.GetMapper<Customer, CustomerDTO>();
var mapper = ObjectMapperManager.DefaultInstance
.GetMapper<User, UserDTO>(
new DefaultMapConfig()
.ConvertUsing<List<Customer>, IEnumerable<CustomerDTO>>(
a => a.Select(customerMapper.Map))
);
This can be done creating a custom class, implementing the interface "ICustomConverterProvider" and adding a ConvertGeneric to the "DefaultMapConfig".
Looking on the source code of EmitMapper, i found a class named "ArraysConverterProvider", which is the default generic converter from ICollections to Arrays.
Adapting the code from this class to work with IEnumerable collections:
class GenericIEnumerableConverterProvider : ICustomConverterProvider
{
public CustomConverterDescriptor GetCustomConverterDescr(
Type from,
Type to,
MapConfigBaseImpl mappingConfig)
{
var tFromTypeArgs = DefaultCustomConverterProvider.GetGenericArguments(from);
var tToTypeArgs = DefaultCustomConverterProvider.GetGenericArguments(to);
if (tFromTypeArgs == null || tToTypeArgs == null || tFromTypeArgs.Length != 1 || tToTypeArgs.Length != 1)
{
return null;
}
var tFrom = tFromTypeArgs[0];
var tTo = tToTypeArgs[0];
if (tFrom == tTo && (tFrom.IsValueType || mappingConfig.GetRootMappingOperation(tFrom, tTo).ShallowCopy))
{
return new CustomConverterDescriptor
{
ConversionMethodName = "Convert",
ConverterImplementation = typeof(GenericIEnumerableConverter_OneTypes<>),
ConverterClassTypeArguments = new[] { tFrom }
};
}
return new CustomConverterDescriptor
{
ConversionMethodName = "Convert",
ConverterImplementation = typeof(GenericIEnumerableConverter_DifferentTypes<,>),
ConverterClassTypeArguments = new[] { tFrom, tTo }
};
}
}
class GenericIEnumerableConverter_DifferentTypes<TFrom, TTo> : ICustomConverter
{
private Func<TFrom, TTo> _converter;
public IEnumerable<TTo> Convert(IEnumerable<TFrom> from, object state)
{
if (from == null)
{
return null;
}
TTo[] result = new TTo[from.Count()];
int idx = 0;
foreach (var f in from)
{
result[idx++] = _converter(f);
}
return result;
}
public void Initialize(Type from, Type to, MapConfigBaseImpl mappingConfig)
{
var staticConverters = mappingConfig.GetStaticConvertersManager() ?? StaticConvertersManager.DefaultInstance;
var staticConverterMethod = staticConverters.GetStaticConverter(typeof(TFrom), typeof(TTo));
if (staticConverterMethod != null)
{
_converter = (Func<TFrom, TTo>)Delegate.CreateDelegate(
typeof(Func<TFrom, TTo>),
null,
staticConverterMethod
);
}
else
{
_subMapper = ObjectMapperManager.DefaultInstance.GetMapperImpl(typeof(TFrom), typeof(TTo), mappingConfig);
_converter = ConverterBySubmapper;
}
}
ObjectsMapperBaseImpl _subMapper;
private TTo ConverterBySubmapper(TFrom from)
{
return (TTo)_subMapper.Map(from);
}
}
class GenericIEnumerableConverter_OneTypes<T>
{
public IEnumerable<T> Convert(IEnumerable<T> from, object state)
{
if (from == null)
{
return null;
}
return from;
}
}
This code is just a copy with a minimum of adaptation as possible and can be applyed to objects with many levels of hierarchy.
You can use the above code with the following command:
new DefaultMapConfig().ConvertGeneric(
typeof(IEnumerable<>),
typeof(IEnumerable<>),
new GenericIEnumerableConverterProvider());
This saved my day and I hope to save yours too! hehehe

Resources