Basic and simple linq to sql, not sure what's wrong - c#

I a have a simple linq to sql query and for some reason the .take() doesn't work. I tried to add skip() as well thinking that maybe it needed some starting point from where to take the records but the results are still same and rather than taking only 10 records, it takes all 240 records.
Would appreciate if somebody can tell me what's going on. Thanks in advance.
The code is:
var types = (from t in EventTypes.tl_event_types
select new
{
type_id = t.event_type_id,
type_name = t.type_name
}).Take(10);

I'm assuming that by naming conventions that EventTypes is your object. You need to select from your data context... So
var types = (from t in dataContext.EventTypes.tl_event_types
select new
{
type_id = t.event_type_id,
type_name = t.type_name
}).Take(10);
should work.

Related

How can I map a "select all" query with 2 tables using SqlQuery

I'm trying to retrieve all fields from two joined tables to any kind of a c# object.
So I'm trying to run this code:
var query = #$"EXEC('select *
from persons p join students s on p.id=s.id
where p.id = 21')";
var result = _context.Database.SqlQuery<?>(query).ToList();
But I don't get what should be instead of the question mark.
I've tried List<object> and Dictionary<string,string> but since I couldn't get exactly how this is being mapped, I don't understand to what it can be mapped.
There is a somewhat similar question here but its solution only addresses two columns, and it apparently doesn't support returning nulls.
You can try creating a stored procedure or a function in the SQL level.
Then, just select then generated table / result.
So, you already have an idea of what class it is.
I frequently use the dynamic type like this :
var lst = _context.Database.SqlQuery<dynamic>(query).ToList();
foreach (var item in lst)
{
var myVar = item.myfieldName;
}
It may be preferable to name each field in your query instead of using select *.

How to truncate time part from date in linq query?

Hi I am trying to write linq query to get some details from Sql table. I have created column and storing date and time both. while returning i want to ommit time part. May I know is this possible?
List<returnObject> obj = new List<returnObject>();
obj = (from c in objectDB.NCT_Project
join user in objectDB.NCT_UserRegistration on c.adminUserId equals user.User_Id
where c.adminUserId == userId
select new returnObject
{
id = c.project_Id,
key = c.key,
created = c.createdDate //currently returns datetime
}).ToList();
Any help would be appreciated. Thank you.
Use DbFunctions.TruncateTime method:
created = DbFunctions.TruncateTime(c.createdDate)
According to the docs:
When used as part of a LINQ to Entities query, this method invokes the
canonical TruncateTime EDM function to return the given date with the
time portion cleared.
All you need to do is call 'Date' property on createdDate.
select new returnObject
{
id = c.project_Id,
key = c.key,
created = c.createdDate.Date
}).ToList();
you can try this one.
created = c.createdDate.ToString("HH:mm")
created = c.createdDate.ToString("H:mm")
created = c.createdDate.ToString("hh:mm tt")
created = c.createdDate.ToString("h:mm tt")
also see this question : How to get only time from date-time C#
If you can get date comparison out of the LINQ and leave the rest there, you can use this syntax:
sqlite.Query<Entity>("date comparison").Where("other queries")
The predicate I used in the Query() function had to return only todays orders and looked something like this:
select * from Order where date(orderDate/ 10000000 - 62135596800, 'unixepoch') = date('now')

dynamically pass column names to be selected at runtime in entity framework

We can use the below query to retrieve specific columns using Entity Framework:
var result = context.Contents.Where(c => c.CatalogId == "ABC")
.Select(c => new {c.ContentId, c.ContentName});
I want to pass the column names during runtime.
Can I pass these column names {c.ContentId, c.ContentName} dynamically at runtime.
Thanks
You have to construct a lambda expression at runtime for that to work. There are libraries such as Dynamic LINQ that do some of the work for you, and the Expression APIs themselves aren't too bad to be honest, but I feel it becomes more effort than it is worth at that point. The simplest way is just to drop back down to plain parametrized SQL:
var fields = new[] { "ContentId", "ContentName" };
var q = "SELECT " + string.Join(", ", fields) + " WHERE CatalogId = #Id";
var result = context.Database.SqlQuery<dynamic>(q, new SqlParameter("Id", "ABC"));
Note: Be absolutely certain that the field names here are not coming from user input, because if you don't do that, you're opening yourself up to SQL injection. There are ways to contort the query a bit to avoid SQL injection (add a variable in the query that is parametrized, do a switch case on the variable to select fields), but that is beyond the scope of this answer. Best to entirely avoid interpolating strings from unknown sources into your SQL.

LINQ to DataSet Query Help

I'm really new to LINQ so I'm hoping someone can help me. I've got a database which I need to run a large query from but it's a really old ODBC driver and takes a long time to respond (30+min for even a simple query). It only takes about 2-3min to dump all the data into a dataset however so I figured this was best and then I could run a LINQ to Dataset query. I can't seem to get the query to work and I'm a little confused. I put all the data into an SQL Express database to test the LINQ to SQL query to make sure I was going down the right path. I don't have this option where the application is going to be run as the environment will always be different.
SQL:
SELECT Invoice_detail.Code, Invoice_detail.Description, Product_master.Comment AS Packing, Invoice_detail.QtyInv AS INV, Invoice_detail.QtyBackOrder AS BO, Alternate_product_codes.MasterBarCode AS BarCode, Invoice_detail.PriceAmt AS Price, Invoice_detail.DiscPerc AS Disc, ROUND(Invoice_detail.TaxableAmt/Invoice_detail.QtyInv,2) AS Nett FROM ((Invoice_detail INNER JOIN Product_master ON Invoice_detail.Code = Product_master.Code) INNER JOIN Invoice_header ON Invoice_detail.InternalDocNum = Invoice_header.InternalDocNum AND Invoice_detail.DocType = Invoice_header.DocType) LEFT JOIN Alternate_product_codes ON Invoice_detail.Code = Alternate_product_codes.Code WHERE Invoice_header.DocNum = '{0}' AND Invoice_header.DocType = 1 AND Invoice_detail.LineType = 1 AND Invoice_detail.QtyInv > 0
LINQ to SQL:
from detail in INVOICE_DETAILs
join prodmast in PRODUCT_MASTERs on detail.Code equals prodmast.Code
join header in INVOICE_HEADERs on new { detail.InternalDocNum, detail.DocType } equals new { header.InternalDocNum, header.DocType}
join prodcodes in ALTERNATE_PRODUCT_CODES on detail.Code equals prodcodes.Code into alt_invd
from prodcodes in alt_invd.DefaultIfEmpty()
where
header.DocType == 1 &&
detail.LineType == 1 &&
detail.QtyInv > 0 &&
header.Date > DateTime.Parse("17/07/2011").Date &&
header.DocNum.Trim() == "119674"
select new {
detail.Code,
detail.Description,
Packing = prodmast.Comment,
INV = detail.QtyInv,
BO = detail.QtyBackOrder,
Barcode = prodcodes.MasterBarCode,
Price = detail.PriceAmt,
Disc = detail.DiscPerc,
Nett = Math.Round(Convert.ToDecimal(detail.TaxableAmt/detail.QtyInv),2,MidpointRounding.AwayFromZero)
}
LINQ to Dataset:
var query = from detail in ds.Tables["Invoice_detail"].AsEnumerable()
join prodmast in ds.Tables["Product_master"].AsEnumerable() on detail["Code"] equals prodmast["Code"]
join header in ds.Tables["Invoice_header"].AsEnumerable() on new { docnum = detail["InternalDocNum"], doctype = detail["DocType"] } equals new { docnum = header["InternalDocNum"], doctype = header["DocType"] }
join prodcodes in ds.Tables["Alternate_product_codes"].AsEnumerable() on detail["Code"] equals prodcodes["Code"] into alt_invd
from prodcodes in alt_invd.DefaultIfEmpty()
where
(int)header["DocType"] == 1 &&
(int)detail["LineType"] == 1 &&
(int)detail["QtyInv"] > 0 &&
//header.Field<DateTime>("Date") > DateTime.Parse("17/07/2011").Date &&
header.Field<DateTime>("Date") > DateTime.Now.Date.AddDays(-7) &&
header.Field<string>("DocNum").Trim() == "119674"
select new
{
Code = detail["Code"],
Description = detail["Description"],
Packing = prodmast["Comment"],
INV = detail["QtyInv"],
BO = detail["QtyBackOrder"],
Barcode = prodcodes["MasterBarCode"],
Price = detail["PriceAmt"],
Disc = detail["DiscPerc"],
Nett = Math.Round(Convert.ToDecimal((double)detail["TaxableAmt"] / (int)detail["QtyInv"]), 2, MidpointRounding.AwayFromZero)
};
I need to run the LINQ to DataSet query and then put the results into a DataTable so that I can export to CSV. The query will return many rows so I can see the CopyToDataTable method however that doesn't seem to work unless it is a typed dataset. I'm using the ODBC data adapter fill method so not specifically setting the data types on the Datatables I'm filling. The reason for this is that there is a lot of columns in those tables and setting them all up would be time consuming.
Is LINQ the best option? Am I close? Do I have to set the DataTables up for all the columns and data types? The only other way I can think of is to dump the data into an access database every time and query from there. I'm more curious to get LINQ to work though as I think it's going to be more beneficial for me going forward.
Any help or pointers is appreciated.
Thanks.
Pete.
Consider using POCO objects instead of a DataSet.
Blogs # MSDN
If I understand you correctly, the Linq To Dataset query retrieves the correct information, but you are not able to export the information to csv.
If this is just one csv file you need creating using just the nine fields in your example, you may be able to use a csv library (for example FileHelpers) to export the information.
To give you an example of the extra work involved, you need to define a class eg
[DelimitedRecord(",")]
public class Info
{
[FieldQuoted()]
public string Code ;
[FieldQuoted()]
public string Description ;
[FieldQuoted()]
public string Packing ;
public decimal INV ;
public decimal BO ;
[FieldQuoted()]
public string Barcode ;
public decimal Price ;
public decimal Disc ;
public decimal Nett ;
}
(Note, I'm guessing some of the field types)
You then change your query to use Info , ie
select new Info {
Code = detail["Code"],
...
and finally
FileHelperEngine engine = new FileHelperEngine(typeof(Info));
engine.WriteFile(".\\outputfile.csv", query);
and you are done.

How to execute LINQ query when I have the table`s name stored in a variable

Sorry if I didn't explained it right in the title, but here it goes:
I want to do execute a LINQ query, and I have the name of the table to query stored in a variable:
string tableName = "SomeTable";
DataContext db = new DataContext();
var vResult = from t in db.tableName
where t.Id = ....
Use Reflection on the DataContext to find a property named tableName
You might want to look at DataContext.ExecuteQuery<T>. However, that still doesn't solve the problem that your results might be different types.

Categories