C#, MVC4 - EF Linq searches - c#

Ok, so i have two questions. The first is, let's say that i have an EF called "EntitiesDefinitions", which holds a data table named "stringData" where each cell is defined as a varchar(100) like so:
----------------------------------------------
| | column1 | column2 | column3 | ... |
----------------------------------------------
| row1 | "1,2,3,4" | "5,6,7,8" | "9,a,b,c" | ... |
----------------------------------------------
| row2 | "d,e,f,g" | "h,i,j,k" | "l,m,n,o" | ... |
Each cell contains 4 pieces of information separated by a comma. So what i would like to know is, if there's a way for me to perform a Linq search for the (as an example) the 2rd piece of information of every cell in column1?
using (EntitiesDefinitions ef = new EntitiesDefinitions())
{
var v = (from a in ef.stringData where (a.column1... == "e") select a);
}
I know I could just make 4 columns per cell (column1_1, column1_2, ...column2_1, column2_2,...), but that wouldn't work if i get a table with +250 original columns. So is there a way to perform such searches?
The other question is also related to this. Back in ASP.NET i could send queries to my sql using a string like this:
var stringSql = "SELECT * FROM" + "stringData" + "WHERE ([" + "column1" + "] =" + "e" + ")" + "ORDER by ["+ "column1" +"] ASC;"
Basically, i could define which tables to search for given a string value that represented that property/column. Is there a way to do that with EF linqs?
using (EntitiesDefinitions ef = new EntitiesDefinitions())
{
var v = (from a in ef.stringData where (a.["column1"]... == "e") select a);
}
I'm fairly new with MVC and EF, so I would like to know if this is possible.

From what I understand from your question you can try this out if u sure its always not null:
var res = ef.stringData.Where(c => c.column1.Split(',')[1] == "e")
And for the Second Question where you type "ef.stringData" the name of the table you are querying is "stringData" there is no other way to specify the table name or only if you want to write raw sql queries in EF.

After Fehintola suggestion i was able to do more research specific to those subjects and I was able to find a solution for both questions. In case anyone is interested here's what i came up with:
For the first question, while is not elegant, we can encapsulate data inside in specific characters/delimiters and then we can process search results in nested searches. For example:
using (EntitiesDefinitions ef = new EntitiesDefinitions())
{
//Data could look like";1;*2*&3&#4#"
var v = (from a in ef.stringData where select a); //to store the table
v = c.Where(f => f.column1.Contains("*2*")) //look for the second value
v = x.Where(f => f.column1.Contains("#4.3#"));//look for the forth value
//Do some other stuff...like sending the data to a table
}
For the Second question, you can make raw sql queries like this:
string sqlExample = #"SELECT VALUE a FROM ef.stringData AS a WHERE (a.column1 == '*2*')";
var test = ef.CreateQuery<stringData>(sql).AsQueryable();
This was you can just have variables placed in the sqlExample string to build your query dynamically and you'll get back a IQueryable object you can use to, for example, pass into a table.
I hope this helps someone in the future and thanks to everyone that provided suggestion.

Related

Dynamic Linq Query from Datatable for Pivot Table

I have been struggling with this problem for a while and was wondering if I can get some help.
I have the following items:
Datatable inputdata = //Data from large scale SQL query
var rowvals = (from x in reportattrs.AsEnumerable()
where x.Field<long>("COLFORREPORT") == 0 && x.Field<long>("VALUEFIELD") == 0
orderby x.Field<long>("ORDERDISPLAY")
select new { Name = x.Field<object>("FIELDNAME") });
var colvals = (from x in reportattrs.AsEnumerable()
where x.Field<long>("COLFORREPORT") == 1 && x.Field<long>("VALUEFIELD") == 0
orderby x.Field<long>("ORDERDISPLAY")
select new { Name = x.Field<object>("FIELDNAME") });
var datavals = (from x in reportattrs.AsEnumerable()
where x.Field<long>("COLFORREPORT") == 1 && x.Field<long>("VALUEFIELD") == 1
orderby x.Field<long>("ORDERDISPLAY")
select new { Name = x.Field<object>("FIELDNAME") });
Rowvals are the attributes of the table that we want to filter for in rows, colvals are the column values for the pivot table, datavals are the data sums
What I want to do is create my own custom pivot table routine that allows me to filter and layer in a more sophisticated method.
I am able to get the specific distinct values of one row:
foreach(object val in rowvals){
var distinctValues = dsValues.AsEnumerable()
.Select(row => new {
attribute1_name = row.Field<string>(val)
})
.Distinct();
}
How I can filter out for each value in combination (for a variable number rows and cols) is difficult for me. Not only that, I need to select all the values for each value column so I can aggregate it how I see fit.
Any help would be greatly!
Thanks
Jon
It is not absolutely clear how your input data looks like; since you want to build pivot table I assume that it can be presented as dataset like that (if not it should be converted to the tabular view acceptable for pivot operation):
col1 | col2 | val1
-------------------
C1 | R1 | 1
C1 | R2 | 2
C1 | R1 | 3
C2 | R1 | 4
and desired pivot table is something like that (lets use 'col1' values for pivot table columns, and 'col2' values for rows, and SUM of val1 for values):
| C1 | C2
-----------------
R1 | 4 | 4
R2 | 2 | 0 (or empty)
Data for pivot table like that can be easily calculated by NReco PivotData library with just several lines of code (disclaimer: I'm an author of this library):
// group and calculate measures
var pivotData = new PivotData(
new string[] {"col1","col2"},
new SumAggregatorFactory("val1"),
new DataTableReader(t) );
// get pivot table model for accessing columns/rows/values in easy way
var pivotTable = new PivotTable(
new []{"col2"}, // row dimension(s)
new []{"col1"}, // column dimension(s)
pivotData );
var rowLabels = pivotTable.RowKeys;
var colLabels = pivotTable.ColumKeys;
var cellValue = pivotTable[0, 0].Value; // R1 + C1: 4
var grandTotal = pivotTable[null,null].Value; // 10
Also you can specify several columns for rows/columns and can calculate several measures. Feel free to contact me if something is not clear.

Implementing the All functionality in SQL

I'm trying to write an SQL query where all of a certain group meets a condition.
Update
The Simplifed Table Structure would look like this
ID, TitleID, BlockFromSale
---------------------------
1 | 1 | true
2 | 1 | true
3 | 1 | true
4 | 2 | false
5 | 2 | true
this table would only return the the items TitleID 1.
In actuality I only need the title ID and not the whole item but either will satisfy the conditions.
How Could I write This Linq Query in SQL?
var Query = Data.Items.GroupBy(t => t.TitleID).Where(i => i.All(b => b.BlockFromSale == true));
I try to look at the Sql Query but it just instantly casts it to an object.
Basically I just Need a query that Grabs out all TitleIDs who for each item BlockFromSale is set to true so for the example from the table above it would only return TitleID, 1
It is possible to see the generated SQL of a LINQ query by using the Log property of the query. How to: Display Generated SQL shows an example of this. Basically, the web site shows this example:
db.Log = Console.Out;
IQueryable<Customer> custQuery =
from cust in db.Customers
where cust.City == "London"
select cust;
foreach(Customer custObj in custQuery)
{
Console.WriteLine(custObj.CustomerID);
}
If you want to check predicate p for all rows of a set you can write
NOT EXISTS (... WHERE NOT(p))
Because All(p) == !Any(!p) in pseudo-syntax.
I would guess that ORMs do it this way, too.
There isn't an easy way to do what your asking but a simple but some what slow way would be to use a subQuery
SELECT DISTINCT i.TitleID
FROM Items i
WHERE i.TitleID not in
(SELECT DISTINCT TitleID
FROM items it
WHERE it.BlockFromSale = 0)
so it will remove the titleids who have a false.

Linq collection with not like?

I have a dataGridView with multiple server roles. I'd like to get a collection of server names with roles "not like" webSrvr or client. For example.. DGV:
Servers | Server 1 | Server 2 | Server 3 | Server 4 | Server 5
Role | Database | Proxy | WebSrvr | Client | DC
Is there an easy linq statement to pull the Server 1, 2 and 5 column headers (names)? The reason I'd want to use "not like" or the equivalent is because the roles can have additional values at the end of it. Thoughts?
You could do pretty much what you want ...
var your_name = from str in your_list_source_here
where (str == some_condition)
select ( new { create your object here } )
you could just have the columns you want in the create your object here
here's an example from Linqpad , to illustrate how you can use the new object ...
var words =
from word in "The quick brown fox jumps over the lazy dog".Split()
orderby word.ToUpper()
select word;
var duplicates =
from word in words
group word.ToUpper() by word.ToUpper() into g
where g.Count() > 1
select new { g.Key, Count = g.Count() };
His objects will have the letter and the amount of time it repeats...

Repeat a row multiple times in a gridview

I have a Gridview with a column called Quantity. Each product has it own quantity. I need to show as many rows as the quantity says.
For example, if I have
Car | 4 | $ 20
I need to show 4 rows like
Car | 1 | 20
I can't find a way of doing this. I am using linq to retrieve the data from the database and that is the DataSource of my Gridview.
You can do it using the linq Range method. Assuming you have a linq source like this (trivial example)
var result =
from r in db.SourceTable
select new { r.Name, r.Quantity, r.Price };
Add this to the query
var result =
from r in db.SourceTable
from s in Enumerable.Range(1, record.Quantity)
select new { r.Name, 1, r.Price };
However, this is probably not supported by entity framework (and probably not in any other ORM) so you may need to call .ToList() or .AsEnumerable() first.

Updating record not working in LINQ to SQL

I have this sequence generation query that gets the current sequence and increment it to next value. But the increment is not updating. The nextval is always returning 1, the default value from the database
Entity | StartVal | Increment | CurVal | NextVal
----------------------------------------------------
INVOICE | 0 | 1 | 0 | 1
The nextval should be 3, 5, 7 and so on
int nextVal = 0;
using (var db = new MedicStoreDataContext())
{
DAL.LINQ.Sequence seq = (from sq in db.Sequences
where sq.Entity == entity
select sq).SingleOrDefault();
if (seq != null)
{
nextVal = seq.NextVal.HasValue ? seq.NextVal.Value : 0;
seq.NextVal = nextVal + 2;
db.SubmitChanges();
}
}
Have I left something undone?
UPDATE:
Answer: I needed to set the Primary Key and update Sequence class field to include the Primary Key
Usually this is because it hasnt found the unique identifier (or Primary Key) for a table.
In your data descriptions are you sure the table correctly picked up the unique item? - when I first tried this although I had a unique key etc, the table description in c# didnt mark it as unique, so the linq quietly didnt updated it as I had expected, no errors no warnings. Once I corrected the data table in c#, it all went well.
Isn't that the correct behaviour? wouldn't you expect nextVal to be 1 if CurVal is 0? I may be missing something here but it seems like your overcomplicating it a bit. Isn't what you want to do basically
using (var db = new MedicStoreDataContext())
{
DAL.LINQ.Sequence seq = (from sq in db.Sequences
where sq.Entity == entity
select sq).SingleOrDefault();
if (seq != null)
{
seq.CurVal += seq.Increment;
db.SubmitChanges();
}
}
I don't see why you need the whole nextVal bit at all. Please feel free to correct me if I'm wrong.

Categories