get all the values in Sql table using foreach - asp.net

I need to get all the Ids' from the table "StaffSectionInCharge", it has only two columns StaffId and SectionId, I have values of StaffId and StudentId.....the problem is I can't get the records directly to this table.....am using entity framework and the design of this table is
[EdmRelationshipNavigationPropertyAttribute("Model", "StaffSectionInCharge", "Section")]
public EntityCollection<Section> Sections
{
get
{
return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Section>("Model.StaffSectionInCharge", "Section");
}
set
{
if ((value != null))
{
((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Section>("Model.StaffSectionInCharge", "Section", value);
}
}
}
I can access this table through staff table like
Staff staff = buDataEntities.Staffs.First(s => s.StaffId == StaffId);
Section section = buDataEntities.Sections.First(s => s.SectionId == SectionId);
staff.Sections.Add(section);
buDataEntities.savechanges();
like this I can add the records to this StaffSectionInCharge table....
here I want to get all the StaffIds for the corresponding SectionId
I tried getting like
DataAccess.Staff staffs = new DataAccess.Staff();
foreach (int staff in staffs.Sections.Select(s=>s.SectionId))
{
}
but its not working, can anyone help me here

var staffIds = buDataEntities.Staffs
.Where(st => st.Sections.Any(se => se.SectionId == SectionId))
.Select(st => st.StaffId)
.ToList();
or
var staffIds = buDataEntities.Sections
.Where(se => se.SectionId == SectionId)
.SelectMany(se => se.Staffs.Select(st => st.StaffId))
.Distinct()
.ToList();
Both options should work. If SectionId is the primary key of Section you can smplify the second code to:
var staffIds = buDataEntities.Sections
.Where(se => se.SectionId == SectionId)
.Select(se => se.Staffs.Select(st => st.StaffId))
.SingleOrDefault();

Related

How can add several fields to NEST?

I use Generic and Reflection, so the main problem is add several fields. When i use this code with one field it OK but when i try somehow add new fields it doesn't work:
public static ISearchResponse<T> PartSearch<T>(ElasticClient client, string query, List<string> fieldList = null, int from = 0, int size = 1) where T : class
{
if (client == null)
throw new ArgumentNullException();
if (String.IsNullOrEmpty(query))
throw new ArgumentNullException();
ISearchResponse<T> results;
if (fieldList == null)
{
results = client.Search<T>(q =>
q.Query(q =>
q.QueryString(qs => qs.Query(query))
).From(from).Size(size)
);
}
else
{
results = client.Search<T>(q =>
q.Query(q => q
.QueryString(qs =>
{
//This place where i try to add several fields
List<Field> fildArray = new List<Field>();
foreach (var arg in fieldList)
{
var fieldString = new Field(typeof(T).GetProperty(arg));
fildArray.Add(fieldString);
}
qs.Fields(f => f.Field(fildArray));
qs.Query(query);
return qs;
})
).From(from).Size(size)
);
}
return results;
}
I created an example using Lenient() that can help you with your question:
https://github.com/hgmauri/elasticsearch-with-nest/blob/master/src/Sample.Elasticsearch.Domain/Abstractions/NestExtensions.cs
Problem was in one QueryString parameter Lenient:
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html
Fixed this by setting it on True.

Correctly implementing a search function

I have a search function that searches against a user table and a Vehicle Registration table. There is a one to many relationship between the tables.
The VehicleNumbis a collection of number where I've inserted '-' to make it more readable. Keep in mind that in my DB, the numbers do not have dashes.
So when I'm searching, I removed the '-' and replaced it with an empty string.
So for example, if I have 12345678 in my table, I would have placed a '-' like this 12-345678. So when I'm searching for 12-345678, I expect to get the
the user result.
The issue I'm encountering is that I can not get any result back. Where am I going wrong?
public IQueryable <MyModel> Method(string search)
{
var userResult = _context.User.Select(u => new MyModel()
{
UserName = u.UserName,
FullName = u.FullName,
Status = u.MStatus,
VehicleNumb = u.Vehicle
.Where(v => v.Registration.VehicleNumb.Any()
&& v.Registration.VehicleNumb != null)
.Select(x => v.Registration.VehicleNumb.Insert(2, "-"))
});
if(!string.IsNullOrEmpty(search.Replace("-", "")))
{
foreach(var item in userResult)
{
foreach(var item2 in item.VehicleNumb)
{
userResult = userResult
.Where(x => item2.Replace("-", "").Contains(search.Replace("-", "")));
}
}
return userResult;
}
}

Complex LINQ query - multiple table relationships

I have a books database, which has an ICollection of authors. I want to return the author object based on the AuthorId using LINQ.
Book db
int BookId
string Name { get; set; }
public ICollection<Author> Authors { get; set; }
Author db
int AuthorId
string Name
ICollection<Quote> Quotes { get; set; }
ICollection<Penname> Pennames { get; set; } - Edit: Added for clarity
I have tried:
var test = _context.Book.Include(x => x.Authors).Include("Authors.Quotes")
.Select(y => y.Authors)
Which gave me:
EntityQueryable<ICollection<Authors>>
[0] {HashSet<Author>} [0]{Author} [1]{Author} [3]{Author}
[1] {HashSet<Author>} [0]{Author} [1]{Author}
[2] {HashSet<Author>} [0]{Author} [1]{Author}
I just can't figure out how to iterate though the Authors in the Authors list. Something like the below:
var id = 2
var test = _context.Book.Include(x => x.Authors).Include("Authors.Quotes")
.Select(y => y.Authors.Select(x => x.Author).Where(x => x.AuthorId == id))
If I ever do a major update I might use elastic...
Update #Marko Papic:
Thanks. Weirdly if I use the below to get a list of books with authors, I get the quotes and pennames lists populated as I expect
var test = _context.Book.Include(x => x.Authors)
.ThenInclude(x => x.Quotes)
.Include(x => x.Authors)
.ThenInclude(x => x.Pennames)
However if I use SelectMany, then the quotes and pennames end up as null
var test = _context.Book.Include(x => x.Authors)
.ThenInclude(x => x.Quotes)
.Include(x => x.Authors)
.ThenInclude(x => x.Pennames)
.SelectMany(x => x.Authors).Where(x => x.AuthorId == id);
Author myauthor
int AuthorId = 2
string Name = "Bob"
ICollection<Quote> Quotes = null
ICollection<Penname> Pennames = null
You can use SelectMany:
var test = _context.Book.Include(x => x.Authors).ThenInclude(x => x.Quotes)
.SelectMany(x => x.Authors).Where(x => x.AuthorId == id);
I think the includes are ignored because the result type of the query is not the same of the type of your dbset with when you start, from the documentation:
If you change the query so that it no longer returns instances of the
entity type that the query began with, then the include operators are
ignored.
I assume the relationship between Books and Authors is many to many, if that is the case then this is how I would do your query:
var query=_context.Authors.Include(a=>a.Books)
.Include(a=>a.Quotes)
.Include(a=>a.Pennames)
.Where(a=> a.AuthorId == id);

ASP.NET Passing parameter and return values

I'm trying to understand how to properly pass a parameter and more importantly, return one or several values.
In the main method I have:
public IActionResult FinVD()
{
var user = from d in _context.Roles
join userRole in _context.UserRoles on d.Id equals userRole.RoleId
join usuario in _context.Users on userRole.UserId equals usuario.Id
where usuario.UserName == User.Identity.Name
select d;
var cargo = user.FirstOrDefault();
var cargodesc = cargo.Name;
ListaTienda(cargodesc);
//...More code
FinanzaDIndexData ventadiaria = new FinanzaDIndexData()
{
MedioPagos = medio_pago,
hechosf_periodo = fecha,
//Here lies the problem. Is not initialized in the context if the code stays like this.
HechosFinanzaL = ListaHechosFinanza,
};
return View(ventadiaria);
}
Passing this parameter to ListaTienda will do the following:
Generate a ViewBag
Generate a List
private void ListaTienda(string cargodesc)
{
if (cargodesc == "Jefe")
{
List<Tienda> ListaTienda = new List<Tienda>();
ListaTienda = _context.Stores.Where(j => j.Districts.Provincias.provincia_jefe == User.Identity.Name && j.tienda_vigencia_reg == 1).OrderBy(j => j.tienda_nombre).ToList();
ListaTienda.Insert(0, new Tienda { tienda_id = 0, tienda_nombre = "-- Seleccione Tienda --" });
ViewBag.ListaTienda = ListaTienda;
List<HechosFinanza> ListaHechosFinanza = new List<HechosFinanza>();
ListaHechosFinanza = _context.HechosFinanza.Include(f => f.Devices).ThenInclude(f => f.Machines).ThenInclude(f => f.Stores).ThenInclude(f => f.Districts).ThenInclude(f => f.Provincias)
.Where(f => f.finanzas_id == 1 &&
f.Devices.Machines.Stores.Districts.Provincias.provincia_jefe == User.Identity.Name)
.OrderBy(f => f.Devices.Machines.Stores.tienda_nombre).ToList();
//...more code
}
}
The problem:
When I go back to the main method, I have a List waiting to be populated with the result of ListaHechosFinanza but I get the message:
The name 'ListaHechosFinanza' does not exist in the actual context
Do I have to declare an empty List<HechosFinanza> in the main method, pass it as a parameter and let it be modified using ref? or without it since is a List? Like this?:
public IActionResult FinVD()
{
var user = from d in _context.Roles
join userRole in _context.UserRoles on d.Id equals userRole.RoleId
join usuario in _context.Users on userRole.UserId equals usuario.Id
where usuario.UserName == User.Identity.Name
select d;
var cargo = user.FirstOrDefault();
var cargodesc = cargo.Name;
List<HechosFinanza> ListaHechosFinanza = new List<HechosFinanza>();
ListaTienda(cargodesc, ListaHechosFinanza);
//... more code
FinanzaDIndexData ventadiaria = new FinanzaDIndexData()
{
MedioPagos = medio_pago,
hechosf_periodo = fecha,
HechosFinanzaL = ListaHechosFinanza,
};
return View(ventadiaria);
}
Part 2:
private void ListaTienda(string cargodesc, List<HechosFinanza> ListaHechosFinanza)
{
if (cargodesc == "Jefe")
{
List<Tienda> ListaTienda = new List<Tienda>();
ListaTienda = _context.Stores.Where(j => j.Districts.Provincias.provincia_jefe == User.Identity.Name && j.tienda_vigencia_reg == 1).OrderBy(j => j.tienda_nombre).ToList();
ListaTienda.Insert(0, new Tienda { tienda_id = 0, tienda_nombre = "-- Seleccione Tienda --" });
ViewBag.ListaTienda = ListaTienda;
//List<HechosFinanza> ListaHechosFinanza = new List<HechosFinanza>();
ListaHechosFinanza = _context.HechosFinanza.Include(f => f.Devices).ThenInclude(f => f.Machines).ThenInclude(f => f.Stores).ThenInclude(f => f.Districts).ThenInclude(f => f.Provincias)
.Where(f => f.finanzas_id == 1 &&
f.Devices.Machines.Stores.Districts.Provincias.provincia_jefe == User.Identity.Name)
.OrderBy(f => f.Devices.Machines.Stores.tienda_nombre).ToList();
}
ListaTienda() method needs to return a list of HechosFinanza.
So change it to
private IList<HechosFinanza> ListaTienda(string cargodesc, List<HechosFinanza> ListaHechosFinanza)
Also, since this method returns a value now, you need to assign its value to ListaHechosFinanza in FinVD() which will look like:
IList<HechosFinanza> ListaHechosFinanza = ListaTienda(cargodesc, ListaHechosFinanza);
This error message means that the variable ListaHechosFinanza is not 'visible' to the ListaTienda method as this is a local variable.
The name 'ListaHechosFinanza' does not exist in the actual context
Head over to MSDN to understand the scoping of the variables which is at the crux of data sharing and access.
Also, always code to interface, not implementation. More info here - What does it mean to "program to an interface"?

Showing linked table items in a controller/view

I have a room class, which has 3 linked tables, Property, Sex (as in Male/Female), Stage.
I can get the Index controller to return the linked table items, by using Include:
var rooms = db.Rooms.Include(r => r.Property).Include(r => r.Sex).Include(r => r.Stage);
What I don't know is, how to you include these linked table items in the Details controller:
Room room = db.Rooms.Find(id);
The full controllers are listed below:
//
// GET: /Room/
public ActionResult Index()
{
var rooms = db.Rooms.Include(r => r.Property).Include(r => r.Sex).Include(r => r.Stage);
return View(rooms.ToList());
}
//
// GET: /Room/Details/5
public ActionResult Details(int id = 0)
{
Room room = db.Rooms.Find(id);
if (room == null)
{
return HttpNotFound();
}
return View(room);
}
Thanks for any help,
Mark
After Include statments you could use LINQ's SingleOrDefault method
Like this:
Room room = db.Rooms.Include(r => r.Property)
.Include(r => r.Sex)
.Include(r => r.Stage)
.SingleOrDefault(r => r.Id = id);

Resources