i am doing this in WPF and i am using entity-framework .
this is my query code in my CRUD class file :
public class QuestionHint
{
public int? QuestionNo { get; set; } //change the type accordingly
public int? ActivityID { get; set; } //change the type accordingly
public int? TaskID { get; set; } //change the type accordingly
public string Answer { get; set; } //change the type accordingly
public string QuestionContent { get; set; } //change the type accordingly
public string joined { get; set; } //change the type accordingly
public string joinOption { get; set; } //change the type accordingly
}
public IList<QuestionHint> GetListKeys(int listTask, int listActivity)
{
IList<QuestionHint> lstRecords = context.questionhints.GroupBy(x => new { x.QuestionNo, x.ActivityID, x.TaskID }).ToList().Select(g => new QuestionHint()
{
QuestionNo = g.Key.QuestionNo,
ActivityID = g.Key.ActivityID,
TaskID = g.Key.TaskID,
joined = String.Join(" ",
g.OrderBy(q => q.questionhintID)
.Select(i => i.QuestionContent + "[" + i.Answer + "]")),
joinOption = String.Join(" ",
g.OrderBy(q => q.questionhintID)
.Select(a => "[" + a.Option1 + "," + a.Option2 + "]"))
}).Where(x => x.TaskID == listTask && x.ActivityID == listActivity)
//.Take(50)
.ToList();
return lstRecords;
}
i call this in code behind :
private DAO.DAOQuestionHint qh = new DAO.DAOQuestionHint();
public MainWindow2()
{
InitializeComponent();
PopulateQuestion(1, 5);
}
private void PopulateQuestion(int activityID, int taskID)
{
IList<QuestionHint> lstQuestionHints = qh.GetListKeys(taskID, activityID); // ERROR
//codes here...
}
i am getting this error in the code behind of my xaml.cs :
Cannot implicitly convert type
'System.Collections.Generic.IList'
to 'System.Collections.Generic.IList'. An
explicit conversion exists (are you missing a cast?)
iStellar is the name of the project. DAOQuestionHint is the name of the CRUD class file.
There is no error in the CRUD class file , i use the same query to retrieve records in the other project and it works well , don't know why it don't work in here.
You're using different capitalization for the generic argument in each example - IList<QuestionHint> in GetListKeys() and IList<Model.questionhint> in PopulateQuestion(). I'd guess these refer to similarly named but different types.
Related
I`m having simple method which builds IQueryable and returns it.
public IQueryable<ClassDTO> ReportByNestedProperty()
{
IQueryable<Class> query = this.dbSet;
IQueryable<ClassDTO> groupedQuery =
from opportunity in query
group new
{
ItemGroup = opportunity.OpportunityStage.Name,
EstimatedRevenue = opportunity.EstimatedRevenue,
CostOfLead = opportunity.CostOfLead
}
by new
{
opportunity.OpportunityStage.Name,
opportunity.OpportunityStage.Id
}
into item
select new ClassDTO()
{
ItemGroup = string.IsNullOrEmpty(item.Key.Name) ? "[Not Assigned]" : item.Key.Name,
Count = item.Select(z => z.ItemGroup.Name).Count(), // int
Commission = item.Sum(z => z.EstimatedRevenue), // decimal
Cost = item.Sum(z => z.CostOfLead), // decimal?
};
return groupedQuery;
}
This is fine. The thing i need is to create method with same return type, but groupby by different prperties dynamically. So from the above code I want to have 3 dynamic parts which will be passed as params:
ItemGroup = opportunity.OpportunityStage.Name
and
by new
{
opportunity.OpportunityStage.Name,
opportunity.OpportunityStage.Id
}
So the new method should be like this
public IQueryable<ClassDTO> ReportByNestedProperty(string firstNestedGroupByProperty, string secondNestedGroupByProperty)
{
// TODO: ExpressionTree
}
And call it like this:
ReportByNestedProperty("OpportunityStage.Name","OpportunityStage.Id")
ReportByNestedProperty("OtherNestedProperty.Name","OtherNestedProperty.Id")
ReportByNestedProperty("OpportunityStage.Name","OpportunityStage.Price")
So the main thing is to create expressions with these two selects:
opportunity.OpportunityStage.Name,
opportunity.OpportunityStage.Id
I have tried toe create the select expressions, groupby, the creation of Anonomoys classes and the DTO Class but I just cant get it right.
EDIT:
Here are the classes involved:
public class ClassDTO
{
public ClassDTO() { }
[Key]
public string ItemGroup { get; set; }
public decimal Commission { get; set; }
public decimal? Cost { get; set; }
public int Count { get; set; }
}
Class obj is a pretty big one so i`m posting just part of it
public partial class Class
{
public Class() { }
[Key]
public Guid Id { get; set; }
public Guid? OpportunityStageId { get; set; }
[ForeignKey(nameof(OpportunityStageId))]
[InverseProperty(nameof(Entities.OpportunityStage.Class))]
public virtual OpportunityStage OpportunityStage { get; set; }
}
public partial class OpportunityStage
{
public OpportunityStage()
{
this.Classes = new HashSet<Class>();
}
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
[InverseProperty(nameof(Class.OpportunityStage))]
public virtual ICollection<TruckingCompanyOpportunity> Classes{ get; set; }
}
I have simplified your Grouping query and introduced private class IdName which should replace anonymous class usage:
class IdName
{
public int Id { get; set; }
public string Name { get; set; } = null!;
}
static Expression MakePropPath(Expression objExpression, string path)
{
return path.Split('.').Aggregate(objExpression, Expression.PropertyOrField);
}
IQueryable<ClassDTO> ReportByNestedProperty(IQueryable<Class> query, string nameProperty, string idProperty)
{
// Let compiler to do half of the work
Expression<Func<Class, string, int, IdName>> keySelectorTemplate = (opportunity, name, id) =>
new IdName { Name = name, Id = id };
var param = keySelectorTemplate.Parameters[0];
// generating expressions from prop path
var nameExpr = MakePropPath(param, nameProperty);
var idExpr = MakePropPath(param, idProperty);
var body = keySelectorTemplate.Body;
// substitute parameters
body = ReplacingExpressionVisitor.Replace(keySelectorTemplate.Parameters[1], nameExpr, body);
body = ReplacingExpressionVisitor.Replace(keySelectorTemplate.Parameters[2], idExpr, body);
var keySelectorLambda = Expression.Lambda<Func<Class, IdName>>(body, param);
// finalize query
IQueryable<ClassDTO> groupedQuery = query
.GroupBy(keySelectorLambda)
.Select(item => new ClassDTO()
{
ItemGroup = string.IsNullOrEmpty(item.Key.Name) ? "[Not Assigned]" : item.Key.Name,
Count = item.Count(x => x.Name), // int
Commission = item.Sum(x => x.EstimatedRevenue), // decimal
Cost = item.Sum(x => x.CostOfLead), // decimal?
});
return groupedQuery;
}
I want to sync s.UrunNavigation.Uadi with Adi but It gives this error
cannot implicitly convert type 'bool' to 'string'
Cannot convert lambda expression to delegate type
'System.Func' because some of the return
types in the block are not implicitly convertible to the delegate
return type
public ActionResult UrunMiktarIcin(string Adi, string OcakUrun)
{
string reply;
if (OcakUrun == "urun")
{
reply = _context.UrunMiktari
.Include(u => u.HangiOcakNavigation)
.Include(u => u.UrunNavigation)
.Where(s => s.UrunNavigation.Uadi = Adi)
.Select(u => new
{
UrunAdi = u.UrunNavigation.Uadi,
OcakAdi = u.HangiOcakNavigation.NeredekiOcak,
UrunSayisi = u.UMiktari
});
return Json();
}
My UrunMiktari Model:
public partial class UrunMiktari
{
public int Id { get; set; }
public int Urun { get; set; }
public int UMiktari { get; set; }
public int HangiOcak { get; set; }
public virtual CayOcaklari HangiOcakNavigation { get; set; }
public virtual Urunler UrunNavigation { get; set; }
}
My Urunler Model:
public partial class Urunler
{
public Urunler()
{
UrunCikis = new HashSet<UrunCikis>();
UrunGiris = new HashSet<UrunGiris>();
UrunMiktari = new HashSet<UrunMiktari>();
}
public int Id { get; set; }
public string Uadi { get; set; }
public decimal SatisFiyati { get; set; }
public decimal AlisFiyati { get; set; }
public bool AktifPasif { get; set; }
public string Barcodu { get; set; }
public virtual ICollection<UrunCikis> UrunCikis { get; set; }
public virtual ICollection<UrunGiris> UrunGiris { get; set; }
public virtual ICollection<UrunMiktari> UrunMiktari { get; set; }
}
I try "s => s.UrunNavigation.Uadi == Adi"
reply = _context.UrunMiktari.Include(u => u.HangiOcakNavigation).Include(u => u.UrunNavigation).Where(s => s.UrunNavigation.Uadi == Adi).Select(u => new { UrunAdi = u.UrunNavigation.Uadi ,OcakAdi = u.HangiOcakNavigation.NeredekiOcak, UrunSayisi = u.UMiktari })
It gives this error:
cannot implicitly convert type 'system.linq.iqueryable <>to 'string'
_context.UrunMiktari.Include(u => u.HangiOcakNavigation).Include(u => u.UrunNavigation).Where(s => s.UrunNavigation.Uadi == Adi).Select(u => new { UrunAdi = u.UrunNavigation.Uadi ,OcakAdi = u.HangiOcakNavigation.NeredekiOcak, UrunSayisi = u.UMiktari })
returns a type of IEnumerable<{ UrunAdi, OcakAdi, UrunSayisi }>, not a type of string.
It looks like you want to return a json array?
try this
public ActionResult UrunMiktarIcin(string Adi, string OcakUrun)
{
if (OcakUrun == "urun")
{
var reply = _context.UrunMiktari
.Include(u => u.HangiOcakNavigation) // this is not necessary because manually projecting
.Include(u => u.UrunNavigation) // this is not necessary because manually projecting
.Where(s => s.UrunNavigation.Uadi == Adi) // Had a single `=`, need `==`.
.Select(u => new
{
UrunAdi = u.UrunNavigation.Uadi,
OcakAdi = u.HangiOcakNavigation.NeredekiOcak,
UrunSayisi = u.UMiktari
});
return Json(reply);
}
return Json();
}
You also have an assignment op (=), you need a comparison op (==).
could anyone help me please? Following my code and "An unhandled exception of type 'System.InvalidCastException' occurred in GelatoProject.exe
Additional information: Unable to cast object of type 'System.String' to type 'GelatoProject.RecipeVariables'." is the message.
// ...
using (var db = new GelatoProjectDBEntities())
{
RecipeVariables selected =
(RecipeVariables)comboBoxRecipeDetail.SelectedItem;
var results = (from x in db.Recipe_Parameters
select new RecipeVariables
{
Id = x.Id,
RecipeDetail = x.recipeDetail,
Parameter = x.parameter,
RangeDetail = x.rangeDetail,
RangeValue = x.value.ToString()
}
)
.Where(x => x.RecipeDetail == selected.RecipeDetail && x.Parameter == "totalsolids" && x.RangeDetail == "Max")
.FirstOrDefault();
totsolidsRangeMax = decimal.Parse(results.RangeValue);
MessageBox.Show(totsolidsRangeMax.ToString());
}
// ...
class RecipeVariables
{
public int Id { get; set; }
public string NameIngredient { get; set; }
public string Brand { get; set; }
public string LBName { get { return NameIngredient + " - " + Brand;}}
public string RecipeDetail { get; set; }
public string Parameter { get; set; }
public string RangeDetail { get; set; }
public string RangeValue { get; set; }
}
RecipeVariables selected = (RecipeVariables)comboBoxRecipeDetail.SelectedItem;
comboBoxRecipeDetail.SelectedItem is a string - text that you see when you clicked on the combobox. It can not be cast to RecipeVariables
Change your code to:
using (var db = new GelatoProjectDBEntities())
{
RecipeVariables selected = new RecipeVariables()
{
RecipeDetail = (string)comboBoxRecipeDetail.SelectedItem
};
// var results = ...
}
This will create a new RecipeVariables object and then set its RecipeDetail property to the text for selected combobox item.
I have a simple web service calling a sql view table through entity framework. I can bring all the columns in string fine but not the column in numeric like UID_NUM(numeric(38,8), null) in SQL. I have AddressALL class to set columns like below and error out at p.UID_NUM in LINQ.
public class GISAddressWebService : System.Web.Services.WebService
{
[WebMethod]
public AddressALL[] getAddress()
{
try
{
List<view_COBADDRESS> address = new List<view_COBADDRESS>();
using (GISAddressEntities database = new GISAddressEntities())
{
return database.view_COBADDRESS
.Where(p => p.UNIT_NUM == "103")
.Select(p => new AddressALL { UID_NUM = p.UID_NUM, ADD_FULL = p.ADD_FULL, POSTALCITY = p.POSTALCITY, ZIP5 = p.ZIP5}).ToArray();
}
}
catch (Exception)
{
return null;
}
}
}
public class AddressALL
{
public double UID_NUM { get; set; }
public string TLID { get; set; }
public string ADD_FULL { get; set; }
public string POSTALCITY { get; set; }
public string STATE { get; set; }
public string ZIP5 { get; set; }
public string IN_OUT { get; set; }
}
The decimal has more significant figures than the double, therefore it can be more precise and it also takes up slightly more memory. Because of this difference fou must explicitly program this change of type through (double)p.UID_NUM.
return database.view_COBADDRESS
.Where(p => p.UNIT_NUM == "103")
.Select(p => new AddressALL { UID_NUM = System.Convert.ToDouble(p.UID_NUM), ADD_FULL = p.ADD_FULL, POSTALCITY = p.POSTALCITY, ZIP5 = p.ZIP5}).ToArray();
MSDN
The obvious solution, instead of
.Select(p => new AddressALL
{
UID_NUM = p.UID_NUM,
ADD_FULL = p.ADD_FULL,
POSTALCITY = p.POSTALCITY,
ZIP5 = p.ZIP5
});
write
.Select(p => new AddressALL
{
UID_NUM = Convert.ToDouble(p.UID_NUM),
ADD_FULL = p.ADD_FULL,
POSTALCITY = p.POSTALCITY,
ZIP5 = p.ZIP5
});
In your select statement .Select(p => new AddressALL{ ... }) you are doing a projection that is trying to pick a new object of type AddressALL for each p, and you are using the object initializer syntax {...} to match the properties of your source objects p with the properties of your target type AddressALL.
Your error message however suggests your p.UID_NUM is of type decimal, while the UID_NUM property on your AddressALL is of type double. Therefore you have to convert the values to the necessary target type.
I am getting a error in the line below.
temp.day1_veh_p = string.Join(Environment.NewLine, day1.Where(x => x.plannedTriips == 1).Select(x => new {value=x.vehicleNumber+":"+x.shiftCompletedOn }).Cast<string>().ToArray());
Th error Message being
Unable to cast object of type '<>f__AnonymousType0`1[System.String]' to type 'System.String'.
The list day1 is of type
public class tripDetails
{
public string accountID { get; set; }
public string supplierName { get; set; }
public string supplierCode { get; set; }
public DateTime shiftFrom { get; set; }
public DateTime shiftTo { get; set; }
public int plannedTriips { get; set; }
public int actualTrips { get; set; }
public DateTime forDate { get; set; }
public string vehicleNumber { get; set; }
public string shiftCompletedOn { get; set; }
public class Comparer : IEqualityComparer<tripDetails>
{
public bool Equals(tripDetails x, tripDetails y)
{
return x.supplierCode == y.supplierCode;
}
public int GetHashCode(tripDetails obj)
{
return (obj.supplierCode).GetHashCode();
}
}
}
What exactly Am i doing wrong??
The problem is the new { value = ... }
Replace:
Select(x => new {value=x.vehicleNumber+":"+x.shiftCompletedOn }).Cast<string>()
with
Select(x => x.vehicleNumber+":"+x.shiftCompletedOn)
and you're sorted. You won't need the Cast<string>() at all.
Your original code creates, for each record, a new instance of an anonymous type that has a member called value with the string desired; the second version just creates the string.
In a way, it is no different to trying this:
class Foo
{
public string Bar {get;set;}
}
...
var foo = new Foo { Bar = "abc" };
string s = (string)foo; // doesn't compile
Yes, an anonymous type is not a string, so replace this
.Select(x => new { value = x.vehicleNumber + ":" + x.shiftCompletedOn })
with
.Select(x => x.vehicleNumber + ":" + x.shiftCompletedOn)
Then you can use the query(you don't need to create a new array) for string.Join.
It's also helpful to use multiple lines, it makes your code much more readable:
var vehicles = day1.Where(x => x.plannedTriips == 1)
.Select(x => x.vehicleNumber + ":" + x.shiftCompletedOn);
string str = string.Join(Environment.NewLine, vehicles);
Replace this
(x => new {value=x.vehicleNumber+":"+x.shiftCompletedOn }).Cast<string>()
by this
(x => String.Format("{0}\:{1}", x.vehicleNumber, x.shiftCompletedOn))
When you are doing new { ... } you are creating items of anonymous type and then (Cast<string()) trying explicitly cast to string and such conversion is not defined - youn ends up with appropriate exception.