Entity Framework - Search in 3 tables efficiently - c#

in my DB I have 3 tables like below :
I also have an Autocomplete field in my page in which visitors can search by Country, Province or City and as you know after inserting 3 letter, the search should be conducted by each letter that is inserted. now it seems so costly searching through each table in turn and successively. I also know that City is the most searched field. so what should be the best approach for searching in my case? I should mention that I didn't deploy my web app yet and I can change tables and it's relations.
a code sample would be great.
thanks in advance
MA

Here you can do two things
Create a flat(denormalized data) table combining all the three tables and do the searching in that. Also, you may have to create some triggers on this table to sync the flat table data with data of the actual table.
In a second way, you have to search each table conditionally. Like in your case city is most likely to search then,
a. Search each table
b. Transform the results into a common type
c. Merge the results
d. Sort/select from this merged list

Related

ASP.NET Sorting Multiple SQL Database Tables By Date Range

This past week I was tasked with moving a PHP based database to a new SQL database. There are a handful of requirements, but one of those was using ASP.Net MVC to connect to the SQL database...and I have never used ASP.Net or MVC.
I have successfully moved the database to SQL and have the foundation of the ASP site set up (after spending many hours pouring through tutorials). The issue I am having now is that one of the pages is meant to display a handful of fields (User_Name, Work_Date, Work_Description, Work_Location, etc) but the only way of grabbing all of those fields is by combining two of the tables. Furthermore, I am required to allow the user to search the combined table for any matching rows between a user inputted date range.
I have tried having a basic table set up that displays the correct fields and have implemented a search bar...but that only allows me to search by a single date, not a range. I have also tried to use GridView with its Query Builder feature to grab the data fields I needed (which worked really well), but I can't figure out how to attach textboxes/buttons to the newly made GridView. Using a single table with GridView works perfectly and using textboxes/buttons is very intuitive. I just can't seem to make the same connection with a joined view.
So I suppose my question is this: what is the best way for me to combine these two tables while also still having the ability to perform searches on the displayed data? If I could build this database from scratch I would have just made a table with the relevant data attached to it, but because this is derived from a previously made database it has 12+ years of information that I need to dump into it.
Any help would be greatly appreciated. I am kind of dead in the water here. My inexperience with these systems is getting the better of me. I could post the code that I have, but I am mainly interested in my options and then I can do the research on my own.
Thanks!
It's difficult to offer definitive answers to your questions due to the need for guesswork.
But here are some hints.
You can say WHERE datestamp >= '2017-01-01' AND datestamp < '2018-01-01' to filter all the rows in calendar year 2017. Many variations on this sort of date range filter are available.
Your first table probably has some kind of ID number on each row. Let's call it first.first_id. Your second table probably has its own id, let's call it second.second_id. And, it probably has another id that identifies a row in your first table, let's call it second.first_id. That second.first_id is called a foreign key in the second table to the first table. There can be any number of rows in your second table corresponding to your first table via this foreign key.
If this is the case you can do something like this:
SELECT first.datestamp, first.val1, first.val2, second.val1, second.val2
FROM first
JOIN second ON first.first_id = second.first_id
WHERE first.datestamp >= '2018-06-01' AND first.datestamp < '2018-07-01'
AND (first.val1 = 'some search term' OR second.val1 = 'some search term')
ORDER BY first.datestamp
This makes a virtual table by joining together your two physical tables (FROM...JOIN...).
Then it filters the rows you want from that virtual table (FROM ...).
Then it puts them in the order you want (ORDER BY...).
Finally, it chooses the columns from the virtual table you want in your result set (SELECT ...).
SQL database servers (MySQL, SQL Server, postgreSQL, Oracle and the rest) are very smart about doing this sort of thing efficiently.

How can I save a 3d array in a SQL table

I'm writing code in C#.
It has two type of user: distributors and clients.
Clients can see all products of all distributors and can select them with mentioning the number of each product they need.So they make a list of orders.
Distributors can see lists of orders received from all clients to them. The table should contains "distributor id" and "client id" and "list of ordered products" with their cost and numbers which have ordered.
But I have no idea about saving this data to a single table.i want that each row mentions to a single list of orders from a special client to a special distributor.
Can I have a 3D table or an array or there is a better and more efficient way?
Is it possible to do what you want? Yes.
Should you? No.
I mean, let's say you set up your table. A column for the distributor, a column for the client, and a column for your list of orders (let's use XML for the example) :
DistID ClientID Orders
1 1 <item>A</item><item>B</item><item>C</item>
2 1 <item>D</item><item>C</item>
2 2 <item>E</item><item>A</item><item>F</item><item>G</item>
... so what problems will you run into? First, imagine trying to add or remove an order. You'd have to read the full Orders list, change it, and then write it all back to SQL. That's a lot of overhead, especially if your 'list' has a lot of items or if you're doing a lot of order adds/removes.
Worse, what happens when you need to find anyone that's ordered 'B'? You're going to have to do a full text scan on that column - no index seeks, no optimizations, nothing - just to find the matching items.
Here's my suggestion - take a look at "SQL Normalization" - basically, the guidelines on how to organize SQL data efficiently and effectively. Here are some good starter places:
http://www.studytonight.com/dbms/database-normalization.php
https://www.essentialsql.com/get-ready-to-learn-sql-database-normalization-explained-in-simple-english/
https://www.guru99.com/database-normalization.html
Based on the information you give, it seems you want a data model like this:
Distributor
Id
Name
Client
Id
Name
Product
Id
DistributorId (foreign key)
Order
Id
ProductId (foreign key)
ClientId (foreign key)
Number
That way you can store product orders from clients, and make sure distributors see order of their own products by selecting all orders having productId's that are linked to the selected distributor.

Reference Table through a variable in Entity Framework

I have 5 tables in database Table1, Table2 and so on [All tables have same column name or Table Definition]. I am using Entity Framework in MVC application and C#.
First creating an object of db of Database.
Getting table data as db.Table1.ToList();.
I want to do some thing like this.
list<string> TableNames = new list<string>();
db.TableNames[1].ToList();
Now I know this won't work but is there any way I can get data without hard coding the table names as my Project will deal with 100s of tables with same column names but different data.
This is a Project for a Hospital which will receive data from different locations. Lets say for location A I am expecting 100 cases a day and right now I have 10 locations. So if I combine all this data into one which means 1000 records each day in a single day therefore overtime searching through this table will become performance sensitive.
I am writing this for those who might occur into this same dilemma.....
I had reference a table through EF so the classes got generated into the Model.
Lets say I have 3 tables of same schema tbl_Loc1, tbl_Loc2 and tblLoc3.
public void getDataFromTable(string TableName)
{
using(var ctx = new DBEntities())
{
string query ="Select * from " +TableName;
var data=ctx.tbl_Loc1.SqlQuery(query);
}
}
DBEntities is Database Connection String
In ctx.tbl_Loc1.SqlQuery(query);.............. tbl_loc1 has a class in model which will help in getting data in the same format[As all tables have the same table definition]
There is a model of tbl_Loc1 in EF whereas tbl_Loc2 and tbl_Loc3 are only in Database.
Return this data as IEnumerable list
http://www.entityframeworktutorial.net/Querying-with-EDM.aspx
I echo other commenter's thoughts that you probably can handle this all in one table with a distinguishing column (and some proper indexes on the table). What you've mentioned so far only amounts to hundreds of thousands of records, something that should still perform very well.
However, in order to do what you want the way you state it, you can use reflection to examine the properties of your db object. Any property in there that is a hashset is a property that represents a table, so you can get a list of all the hashset properties, and their names (perhaps with a few tweaks regarding pluralization), which will give you your table names.
For a more sophisticated use of metadata within EF, take a look at How I can read EF DbContext metadata programmatically?.
Also, you may find that SMO is a helpful approach to this kind of thing (nothing preventing you from using it and EF).

Show Child Rows as Columns

It's been a long time since I've done any serious work with relational database, and despite spending the last two hours searching the Internet and taking my best guesses, I just can't work out the necessary SQL Query expression.
I have three related tables:
Players - Contains a list of players
Coaches - Contains a list of coaches
Evaluations - Stores each coach's evaluation of each player as a number.
Each record in the third table therefore includes a field with the PlayerID, CoachID and the rating.
If I have 10 players and 3 coaches, then table 3 should have 30 records in it.
In order to populate these tables, I want to show the coaches names (pulled from the Coaches table) and display them as Columns in a DataGridView that has a Row for each player so that when you enter a value in a player's row under the coach's column, the value get's stored in Table 3 with the appropriate Player and Coach IDs.
I know I've done something like this year's ago in Microsoft Access, but I can't figure out how to build the Query in my Dataset so that I can bind it to the DataGridView.
I tried using the following SQL Query, but it doesn't let me edit the values in the Coach1 and Coach2 columns. I suspect that's because I have a one-many relationship between PlayerList and Evaluations and a one-many relationship between Coaches and Evaluations:
SELECT PlayerList.Number, PlayerList.Name, PlayerList.Year, PlayerList.Height, PlayerList.Notes, PlayerList.AverageSkill, AVG(Evaluations.Skill) AS CoachSkill,
'SELECT Skill FROM Evaluations
WHERE (PlayerID = PlayerList.Number) AND (CoachID = 1)' AS Coach1,
'SELECT Skill FROM Evaluations
WHERE (PlayerID = PlayerList.Number) AND (CoachID = 2)' AS Coach2
FROM Evaluations RIGHT OUTER JOIN
PlayerList ON Evaluations.PlayerID = PlayerList.Number
GROUP BY PlayerList.Number, PlayerList.Name, PlayerList.Year, PlayerList.Height, PlayerList.Notes, PlayerList.AverageSkill
Any help would be appreciated.
Application details: I'm working with C# in Visual Studio Express with a SQL-Server-CE database.
A little more reading leads me to believe that what I want is a PIVOT function which SQL-Server-CE doesn't support.
Thank you.
You could create new DataRows and add columns dynamically. Then add all your created rows to a DataGridView.
This something related to nested Grid, as hierarchical data
go through this link which in detailed explain how to use gridview/datgrids in scenarios like yours.
http://msdn.microsoft.com/en-us/magazine/cc164077.aspx
hope this will resolve your issue.

model classes in a database with my own enum types

I have an application that I need to query lifetables (for insurance calculation).
I was thinking about using XML to store the data, but thought it was a little big, but maybe a little small for using a full-fledged database. So I chose to use SQLite.
In my application, I have enums defining a few different things. For example, GENDER.Male, GENDER.Female. and JOBTYPE.BlueCollar, JOBTYPE.WhiteCollar. etc etc.
I have some methods that look like this: (example)
FindLifeExpectancy(int age, GENDER gender);
FindDeathRate(int age, JOBTYPE jobType);
So my question is: How do you model enums in a database? I don't think it is best practice to use 0 or 1 in the database to store JOBTYPE because that would be meaningless to anyone looking at it. But if you used nvarchar, to store "BlueCollar", there would be a lot of duplicate data.
I don't think GENDER or JOBTYPE should have an entire class, or be apart of the entity model because of the little information they provide.
How is this normally done?
Thanks.
I prefer to statically map my enums in my program to a lookup table in my database. I rarely actually use the lookup table to do a join. As an example I might have the following tables:
Gender
GenderID Name
1 Male
2 Female
Accounts
AccountID GenderID FirstName LastName
1 1 Andrew Siemer
2 2 Jessica Siemer
And in code I would then have my enum defined with the appropriate mapping
public enum Gender
{
Male = 1,
Female = 2
}
Then I can use my enum in code and when I need to use the enum in a LINQ to SQL query I just get its physical value like this
int genderValue = (int)Enum.Parse(typeof(Gender), Gender.Male));
This method may make some folks out there a bit queezy though given that you have just coupled your code to values in your database! But this method makes working with your code and the data that backs that code much easier. Generally, if someone swaps out the ID of a lookup table, you are gonna be hosed in some way or another given that it is mapped across your database any how! I prefer the readability and ubiquitous nature of this design though.
While it's unlikely that you will be adding a new gender, I wouldn't be so sure about the jobtype enum. I'd have used a separate table for both, and have foreign keys to this table every where I need to reference them. The schema will be extensible, the database will automatically check that only possible values are saved in the referencing tables.
The SQL equivalent of 'enums' are lookup tables. These are tables with two (sometimes more) columns:
a code, typically short, numeric or character (ex: 'R', 'S', 'M'...)
a text definition (ex: 'Retired', 'Student', 'Military'...)
extra columns can be used to store definitions, or alternate versions of the text for example a short abbreviation for columnar reports)
The short code is the type of value stored in the database, avoiding the replication you mentioned. For relatively established categories (say Male/Female), you may just use a code, without 'documenting' it in a lookup table.
If you have very many different codes, it may be preferable to keep their lookup in a single SQL table, rather than having a proliferation of dozen of tables. You can simply add a column that is the "category", which itself is a code, designating the nature of the group of codes defined in this category ("marital status", "employment", "education"...)
The info from the lookup tables can be used to populate drop downs and such, in the UI, wherey the end-user sees the clear text but the application can use the code to query the database. It is also used in the reverse direction, to produce the clear text for codes found in the database, for displaying results list and such.
A JOIN construct at the level of SQL is a convenient way to relate the lookup table and the main table. For example:
SELECT Name, Dob, M.MaritalStatus
FROM tblCustomers C
LEFT OUTER JOIN tblMaritalLkup M ON C.MStatus = M.Code
WHERE ...

Categories

Resources