If I had a class defined with this attributes
public class GestionesDataSet
{
public DateTime GestionInicio { get; set; }
public DateTime GestionFin { get; set; }
public Nullable<DateTime> LlamadaInicio { get; set; }
public Nullable<DateTime> LlamadaFin { get; set; }
public string Login { get; set; }
public string Tipificacion { get; set; }
public List<CamposGestion> campoValor { get; set; }
}
And the class called CamposGestion is defined like this
public class CamposGestion
{
public string Nombre { get; set; }
public string Valor { get; set; }
}
How can I Defined a report where I can use the field that refers to the list of the other elements?
I tried to used one dataset where I can set this linq as object data source
var gestiones = (from G in db.Gestion
where
G.IDTipificacion == idTipificacion
&& (from T in db.Tipificacion where T.IdTipificacion == G.IDTipificacion select T.Servicio.IDServicio).AsEnumerable().Contains(idServicio)
select G).AsEnumerable().Select(xx => new GestionesDataSet()
{
GestionInicio = xx.HoraInicio,
GestionFin = xx.HoraFin,
#Tipificacion = ((from T in db.Tipificacion select T).Where(x => x.IdTipificacion == xx.IDTipificacion).Count() > 0 ?
(from T in db.Tipificacion where T.IdTipificacion == xx.IDTipificacion select T.Nombre).FirstOrDefault() : ""),
LlamadaInicio = xx.Llamada.HoraInicio,
LlamadaFin = xx.Llamada.HoraFin,
Login = xx.Llamada.Sesion.Usuario.Nombre,
campoValor = xx.CampoValor.Select(aux => new CamposGestion() {
Nombre = aux.ConfiguracionCampo.Campo.Nombre,
Valor = aux.Valor
}).ToList()
}).ToList();
But what I want to see the report the field that contains the List show's an error like this
Any help would be appreciate.
I would rewrite the query like this:
var gestiones =
from xx in db.Gestion
where
xx.IDTipificacion == idTipificacion
&& (from T in db.Tipificacion
where T.IdTipificacion == xx.IDTipificacion select T.Servicio.IDServicio).AsEnumerable().Contains(idServicio)
select new GestionesDataSet()
{
GestionInicio = xx.HoraInicio,
GestionFin = xx.HoraFin,
#Tipificacion = (from T in db.Tipificacion where T.IdTipificacion == xx.IDTipificacion select T.Nombre).FirstOrDefault() ?? "",
LlamadaInicio = xx.Llamada.HoraInicio,
LlamadaFin = xx.Llamada.HoraFin,
Login = xx.Llamada.Sesion.Usuario.Nombre,
campoValor = xx.CampoValor.Select(aux => new CamposGestion()
{
Nombre = aux.ConfiguracionCampo.Campo.Nombre,
Valor = aux.Valor
}).ToList()
}).ToList();
When you call a projection (Select) after the AsEnumerable was called, LINQ will try to get the navigation objects first from the already loaded ones. If no object is loaded, then will execute a select SQL command for each navigation property used in the projection. If the [DeferredLoadingEnabled][1] property is set to false it won't execute any query and if no object is loaded already (they can be loaded "apriori" with [LoadWith][2]) it will give a NullReferenceException. So, in some situations, calling AsEnumerable might hurt performance. All these things are not valid when AsEnumerable is used in the where parts.
For giving a default value, when no Tipificacion doesn't exist, it can be used the null-coalescing operator, from C#, instead of using the Count method, which creates an extra lookup on the the table.
Now.. to your problem.
SSRS doesn't support binding to a list of items. The column campoValor tries to bind to a list of objects, which is not allowed. So either you create a subreport (there is a section which describes this) or you flatten your data (having the all the properties on one single object) and then use the HideDuplicates property
Related
I have a UI grid which permits sorting by column :
Id
Organisation Name
Organisation type
Departments
1
first
some type
def
2
second
another type
abc, def
2
third
some type
xyz
See the entities below:
public class Organisation
{
public int Code { get; set; }
public string Type { get; set; }
public string Name { get; set; }
public List<Department> Departments { get; set; }
}
public class Department
{
public int Code { get; set; }
public string Name { get; set; }
}
I want to be able to sort the table values by Departments which is a comma separated values that comes from Organization.Departments.Select(p=> p.Name);
I would like to make the sorting as an IQueryable and avoid bringing all the data in memory because After sorting I will apply the pagination and I don't want to bring all the DB records in memory.
I'm using the following extension method for sorting, but it is not working for nested collections:
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string sortProperty, ListSortDirection sortOrder)
{
var type = typeof(T);
var property = type.GetProperty(sortProperty, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
if (property == null)
throw new OperationFailedException($"Sorting by {sortProperty}");
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
var typeArguments = new Type[] { type, property.PropertyType };
var methodName = sortOrder == ListSortDirection.Ascending ? "OrderBy" : "OrderByDescending";
var resultExp = Expression.Call(typeof(Queryable), methodName, typeArguments, source.Expression, Expression.Quote(orderByExp));
return source.Provider.CreateQuery<T>(resultExp);
}
This method works fine for properties that are at object level.
IQueryable I'm using later for sorting looks something like this:
var iQueryableToBeSorted = _dbContext.Organization.Include(p=>p.Departments).AsQueryable();
this is mine model
public class QMSRejection
{
public string Date { get; set; }
public string Grade { get; set; }
public string Resd { get; set; }
public string Remarks { get; set; }
}
this is mine firstpage.xaml.cs from where I am passing a data to another page !
List<QMSRejection> DataToSave = new List<QMSRejection>();
var rej = new QMSRejection();
rej.Date = DateTime.Now.ToShortDateString();
rej.Grade = GradeID;
rej.Resd = ResdId;
DataToSave.Add(rej);
await Navigation.PushAsync(new Rejection2ndForm(DataToSave));
now on the second page I am receiving it, data is coming everything working fine !
public partial class Page2 : ContentPage
{
List<QMSRejection> DataToSave = new List<QMSRejection>();
public Rejection2ndForm(List<QMSRejection> models)
{
InitializeComponent ();
DataToSave = models;
}
}
var rej = new QMSRejection();
rej.Remarks = ent3.Text.ToString();
DataToSave.add(rej);
I have a fields Remarks which I am trying to add to existing data coming from page 1.But these lines are creating another IEnumerable in the datatoSave List and remarks field not getting added to previous data ! What should I do in place of these lines to do ?
As I have to add remarks field through page2.xaml.cs !
this creates a new QMSRejection object and adds it to your list
var rej = new QMSRejection();
rej.Remarks = ent3.Text.ToString();
DataToSave.add(rej);
if you instead want to modify an existing QMSRejection object
// [0] means the first object in the list
DataToSave[0].Remarks = ent3.Text.ToString();
for an internship project I'm developping an app with Xamarin that will allow users to scan barcodes and create sheets of labels and purchases.
To prevent the scanned codes from being lost in case of crash etc, I've implemented SQLite to create a local backup that we could restore.
The structure is as follows : a ListOfLabelLines contains several LabelLine which each contain a Product and different other informations (such as packaging, quantity etc).
ListOfLabelLines.cs :
[Table("ListOfLabelLines")] // Indique le nom de la table qui sera générée par SQLite
public class ListOfLabelLines : BaseItem
{
private string _name { get; set; }
[TextBlob("LabelLinesBlob")]
public ObservableCollection<LabelLine> lines { get; set; }
[TextBlob("ListBlob")]
public List<String> TestList { get; set; }
public string LabelLinesBlob { get; set; } // serialized LabelLines
public string ListBlob { get; set; } // serialized TestList
public ListOfLabelLines()
{
}
public ListOfLabelLines(string name)
{
this._name = name;
lines = new ObservableCollection<LabelLine>();
TestList = new List<String>();
TestList.Add("Test1");
TestList.Add("Test2");
}
public string Name
{
get { return _name; }
set
{
_name = value;
}
}
}
}
These objects ListOfLabelLines contain an ObservableCollection<LabelLine> which I'm serializing by using the TextBlob property from SQLite-net-extensions.
However, when I retrieve the ListOfLabelLines I've stored, the ObservableCollection appears as null :
Example of null collections
Here are the methods I use to store the objects in SQlite :
public void SaveListOfLabelLines(ListOfLabelLines ShelfLabelInstance)
{
var query = from label in database.Table<ListOfLabelLines>()
where label.Name == ShelfLabelInstance.Name
select label;
var res = query.FirstOrDefault();
if (res != null)
{
database.UpdateWithChildren(ShelfLabelInstance);
Console.WriteLine("Label " + ShelfLabelInstance.Name + " updated");
}
else
{
database.InsertWithChildren(ShelfLabelInstance);
Console.WriteLine("Label " + ShelfLabelInstance.Name + " created");
}
}
and to retrieve them :
public void CheckProductsInLabelLine(string n)
{
var query = from LOLL in database.Table<ListOfLabelLines>()
where LOLL.Name == n
select LOLL;
ListOfLabelLines res = query.FirstOrDefault();
The string property linked to the TextBlob, however, contains the JSON object I need.
I thought the ObservableCollection would be obtainable when getting the object in DB since TextBlob is supposed to serialize AND deserialize.
Could anybody help ?
Thanks a lot !
I have a simple entity:
[Table("History")]
public class History
{
[PrimaryKey, AutoIncrement, Column("_id")]
public int Id { get; set; }
[Indexed(Name = "IDX_History", Order = 1, Unique = true)]
public int Prefix { get; set; }
[Indexed(Name = "IDX_History", Order = 2, Unique = true)]
public int Stem { get; set; }
[Indexed(Name = "IDX_History", Order = 3, Unique = true)]
public int Suffix { get; set; }
[Indexed(Name = "IDX_Favourite")]
public bool IsFavourite { get; set; }
public DateTime LastViewed { get; set; } = DateTime.Now;
}
I am trying to do an insert if its new or get the last inserted id if it already exists:
public static int SaveSolutionToHistory(Solution sol)
{
lock (_db)
{
var existingHistory = _db.Table<History>().FirstOrDefault(h => h.Prefix == sol.Prefix.Id
&& h.Stem == sol.Stem.Id
&& h.Suffix == sol.Suffix.Id);
if (existingHistory != null)
{
existingHistory.LastViewed = DateTime.Now;
_db.Update(existingHistory);
return existingHistory.Id;
}
_db.Insert(new History
{
Prefix = sol.Prefix.Id,
Stem = sol.Stem.Id,
Suffix = sol.Suffix.Id
});
return _db.ExecuteScalar<int>("SELECT last_insert_rowid()");
}
}
The top part works fine in returning an id for existing entries but for some reason the insert code always returns 1 when it should return the last inserted primary autoincrement id (as mentioned in the methods XML comment):
_db.Insert(new History
{
Prefix = sol.Prefix.Id,
Stem = sol.Stem.Id,
Suffix = sol.Suffix.Id
});
And this returns the correct id:
return _db.ExecuteScalar<int>("SELECT last_insert_rowid()");
It seems inefficient for me to do two hits like this or to do it as non strongly typed. Is there a reason why the _db.Insert is not returning the correct Id?
I am using VS 2015, with HAXM and Marshmallow x86_64 Google API Image.
I had the same problem, just found the answer here, the full xml comment is:
//
// Summary:
// /// Inserts the given object and retrieves its /// auto incremented primary key
// if it has one. ///
//
// Parameters:
// obj:
// /// The object to insert. ///
//
// Returns:
// /// The number of rows added to the table. ///
What the summary means by "retrieves" is that it updates the value of the PK field in the object which you passed to it, so if you want the last inserted id, you can use that
You can insert rows in the database using Insert. If the table
contains an auto-incremented primary key, then the value for that key
will be available to you after the insert:
public static void AddStock (SQLiteConnection db, string symbol) {
var s = new Stock { Symbol = symbol };
db.Insert (s);
Console.WriteLine ("{0} == {1}", s.Symbol, s.Id);
}
This is mean that ID will be available in object field Id.
https://components.xamarin.com/gettingstarted/sqlite-net
I need simple DropDownList in form and I don't want to create something like ViewModel.
I have two models(tables) in relation 1:n:
public class Course
{
public int ID { get; set; }
public string Name { get; set; }
}
and
public class Project
{
public int ID { get; set; }
public int CourseId { get; set; }
public int ProjectNo { get; set; }
public string Name { get; set; }
public DateTime Deadline { get; set; }
}
In the 'Create Project' I want to have DropDownList with Id (as value) and Name(as text) from Course table(model). In the new project will be insert chosen CourseId. How can I do that as simple as possible?
Any particular reason why you don't want to use a ViewModel? They're very helpful for this type of problem.
If you don't want to use a ViewModel, then you can construct a specific class in your controller that is an aggregate of the properties you need from both classes:
public ActionResult Show(int id)
{
Course course = repository.GetCourse(id); // whatever your persistence logic is here
Project project = projectRepository.GetProjectByCourseId(id);
string CourseName = from c in course where
c.ID == project.courseID
select c.Name;
IEnumerable<SelectListItem> selectList =
from c in course
select new SelectListItem
{
Selected = (c.ID == project.CourseId),
Text = c.Name,
Value = project.CourseId.ToString()
};
//add the selectList to your model here.
return View(); //add the model to your view and return it.
}
It would be far easier to have a ViewModel for this, so you could have a strongly typed view. Let me show you:
public class ProjectCourseViewModel
{
public SelectList ProjectCourseList {get; private set; }
public Project Project {get; private set; }
public Course Course {get; private set; }
public ProjectCourseViewModel(Project project, Course course)
{
ProjectCourseList = GetProjectCourseSelectList(project, course)
Project = project;
Course = course;
}
private SelectList GetProjectCourseSelectList(Project project, Course course)
{
IEnumerable<SelectListItem> selectList =
from c in course
select new SelectListItem
{
Selected = (c.ID == project.CourseId),
Text = c.Name,
Value = project.CourseId.ToString()
};
}
}
And then your controller would be really simple:
public ActionResult Show(int id)
{
Course course = repository.GetCourse(id);
Project project = projectRepository.GetProjectByCourseId(id);
ProjectCourseViewModel pcvm = new ProjectCourseViewModel(project, course)
return View(pcvm);
}
And then your view takes in a strongly typed model, and you don't have to rely on ViewData, which is a Good Thing.
Note: I haven't compiled this, just written it. There are probably compilation bugs.
probably you could solve it using the following example:
in your controller include a Viewbag
{
Viewbag.Course = db.course.ToList();
var project = new project.....
}
And in your View use the following pattern:
#Html.DropDownList("CourseId",
new SelectList(ViewBag.Course as System.Collections.IEnumerable,
"CourseId", "Name", Model.ID))
where each field represent:
•The name of the form field (CourseId)
•The list of values for the dropdown, passed as a SelectList
•The Data Value field which should be posted back with the form
•The Data Text field which should be displayed in the dropdown list
•The Selected Value which is used to set the dropdown list value when the form is displayed
more info at: http://www.asp.net/mvc/tutorials/mvc-music-store-part-5
brgds.
In the Controler:
var CourseName = from c in course where
c.ID == project.courseID
select c.Name;
SelectList sl = new SelectList(CourseName);
ViewBag.names= sl;
in the view :
#Html.DropDownList("Name", (SelectList)ViewBag.names)