C# LINQ to SQL - how to Replace inside "..."? - linq

I have rows in CSV like this:
"04/26/2006,AAA,BBB,\"CCC,DDD , EE,TT\",21.32"
How I can replace all commas inside this row ?
\"CCC,DDD , EE,TT\"
just if Row is between two signs: \"...\"
Because if I do this:
var DBData = from line in lines.Skip(1)
let data = line.Split(new Char[] { ',' })
select new DB_Table
{
...
};
I have spitted Row:
**04/26/2006
AAA
BBB
CCC
DDD
EE
TT
...**
But i need like this:
**04/26/2006
AAA
BBB
CCC DDD EE TT
...**

I would recommend using a CSV parsing library as well, but you can use a Regular Expression as a work around:
var p = new Regex(#"(?<=""[^""]*),(?=[^""]*"")", RegexOptions.Compiled);
var DBData = from line in lines.Skip(1)
let data = p.Replace(line, " ").Split(new Char[] { ',' })
select new DB_Table {
...
};

Related

LinQ Query for selecting multiple data in single row

I have following two tables with data.
Table: Pond
Pond_ID Pond_Owner
01 Nasir
02 John
Table: Fish
Pond_ID Fish_Name
01 Koi
01 Carp
02 Cat Fish
02 Gold Fish
02 Comet
02 Magur
It is noted that Pond_ID field is the primary key in Pond Table and Foreign key in Fish Table. Now I would like to write a LinQ Query to the result like bellow.
Expected Result
Pond_ID Pond_Owner Fish_Name
01 Nasir Koi, Carp
02 John Cat Fish, Gold Fish, Comet, Magur
So anyone can help me to write this linQ query. Thanks in advance.
You have to group them on PondID and OwnerName :
var result = from p in db.pond
join f in db.Fish on p.Pond_Id equals f.Pond_Id
group f by new
{
f.Pond_Id,
f.Owner_name
} into g
select new
{
Owner = g.Key.Owner_Name,
Fishes = String.Join(",",g.Select(x=>x.Fish_Name))
}
then iterate on result set:
foreach(var item in result)
{
Console.WrtieLine(String.Format("Owner Name : {0} , Fishes : {1}",item.Owner,item.Fishes))
}
UPDATE:
var result = from p in db.pond
join f in db.Fish on p.PondID equals f.PondID
group f by new { f.PondID,p.OwnerName } into g
select new { Owner = g.Key.OwnerName, Fishes = String.Join(",",g.Select(x=>x.FishName))};
foreach(var item in result)
{
Console.WriteLine(String.Format("Owner : {0} and Fishses : {1}",item.Owner,item.Fishes));
}
See this WORKING FIDDLE EXAMPLE for more.
You can perform join operations on LINQ like:
var result = (from p in dbContext.Pond
join f in dbContext.Fish
on p.Pond_ID == f.Pond_ID
select new
{
Pond_ID = p.Pond_ID,
Pond_Owner = p.Pond_Owner,
Fish_Name = f.Fish_Name
}).ToList();
Above query will perform full Join. In case you want to perform left outer join, you can do the same operation using DefaultIfEmpty() as:
var result = (from p in dbContext.Pond
join f in dbContext.Fish
on p.Pond_ID == f.Pond_ID into group1
from g1 in group1.DefaultIfEmpty()
select new
{
Pond_ID = p.Pond_ID,
Pond_Owner = p.Pond_Owner,
Fish_Name = g1.Fish_Name
}).ToList();

How to parameterize a linq query?

I've got a data structure that is a list of hash tables, like so:
List<Hashtable> lh = new List<Hashtable>();
And a fairly simple LINQ query for this container:
var query = from h in lh where h["foo"] == "bar" select h;
Is there a way to parameterize the where clause? Something like:
var where_clause = where h["foo"] == "bar";
var query = from h in lh where_clause select h;
Depends on what exactly you're trying to accomplish, but yes you can:
Func<List<Hashtable>, bool> where_clause = h => h["foo"] == "bar";
List<Hashtable> lh = new List<Hashtable>();
var query = lh.Where(where_clause);

LINQ: concatenate multiple int properties into a string

I have an object with two different integer properties in it, and I'm trying to get a a new object in Linq to Entities, combining two integer properties from the same object as concatenated strings, as follows
List<DateRange> collection = (from d in context.dates
select new DateRange
{
DateString = from s in context.Seasons
where s.SeasonID = d.DateID
select string.Format("{0} - {1}", s.StartYear, s.EndYear) }
).ToList<DateRange>();
The string concatenation of the years will not compile.
This will work in LINQ to Objects, provided that each object in objects is a class or struct containing "Number1" and "Number2" fields or properties:
var results = from o in objects
select string.Format("{0} - {1}", o.Number1, o.Number2);
(However, your original should work, as well....)
Assuming you are connecting to a database via LINQ to SQL/Entities, then the String.Format call will likely fail, as with those providers, the select clause is executed within the database. Not everything can be translated from C# into SQL.
To convert your database results into a string like you want to, the following should work:
var temp = (
from d in context.dates
from s in context.Seasons
where s.SeasonID == d.DateID
select new { s.StartYear, s.EndYear }
).ToList(); // Execute query against database now, before converting date parts to a string
var temp2 =
from t in temp
select new DateRange
{
DateString = t.StartYear + " - " + t.EndYear
};
List<DateRange> collection = temp2.ToList();
EDIT:
I had an additional thought. The String.Format call is most likely the problem. I am not sure if it would work or not, but what about a plain-jane concat:
List<DateRange> collection =
(from d in context.dates
select new DateRange
{
DateString = from s in context.Seasons
where s.SeasonID = d.DateID
select s.StartYear + " - " + s.EndYear
}
).ToList<DateRange>();
Your original code works if you really want what you wrote. However, if your really want to get from
var objects = new MyObject[]{
new MyObject {Int1 = 1, Int2 = 2},
new MyObject {Int1 = 3, Int2 = 4}};
something like 1 - 2 - 3 - 4 you can write
var strings = objects.Select(o = > string.Format("{0} - {1}", o.Int1, o.Int2).ToArray();
var output = string.Join(" - ", strings);
using System.Data.Objects.SqlClient;
:
:
List<DateRange> collection = (from d in context.dates
select new DateRange
{
DateString = from s in context.Seasons
where s.SeasonID = d.DateID
select SqlFunctions.StringConvert((double)s.StartYear) + " - " +
SqlFunctions.StringConvert((double)s.EndYear)
}).ToList<DateRange>();
The StringConvert method gets converted into the proper conversion function when the LINQ statement is converted to SQL for execution on the server.

How to use a JOIN in a LINQ query

I have the following table structure, which is imported into an Entity Framework project:
(NOTE: I mislabled T1Name as T2Name in Table1)
alt text http://digitalsamurai.us/images/drawing2.png
I have labeled the Entity Objects. The many-to-many joint table Table5, is represented as an EntityCollection<Entity4> in Entity3, and as an EntityCollection<Entity3> in Entity4 (EntityCollection<T> implements IEnumerable<T>, so it can be queried). I need to construct a result set that is:
T1Name, T2Name, T3Name
This will result in repeat entries for T1Name, and T2Name.
Could someone show me how to write this LINQ query?
Thank you for any help.
var q = from e3 in Context.Table3
from e4 in e3.Table4s // that's your many-to-many
select new
{
Name3 = e3.T3Name,
Name2 = e4.Table2.T2Name,
Name1 = e4.Table1.T1Name // presuming Table1.T2Name in your diagram is a typo
};
"Dot notation":
var q = Context.Table3
.SelectMany(e3 => e3.Select(e4 =>
new {
Name3 = e3.T3Name,
Name2 = e4.Table2.T2Name,
Name1 = e4.Table1.T1Name
});
Notice I didn't use join at all. That's on purpose; you don't need it here.

Read Excel using LINQ

I want to read excel 2003( cannot change as its coming from third party) and group data in List or Dictionary (I don't which one is good)
for example below (Excel formatting )
Books Data [first row and first column in excel]
second row( no records)
Code,Name,IBN [third row (second column, third column]
Aust [fourth row, first column]
UX test1 34 [ fifth row (second column, third column]
......
....
Books Data
Code Name IBN
Aust
UX test1 34
UZ test2 345
UN test3 5654
US
UX name1 567
TG nam2 123
UM name3 234
I am reading excel data using following code( some help from Google)
string filename = #"C:\\" + "Book1.xls";
string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" + filename + ";" +
"Extended Properties=Excel 8.0;";
OleDbDataAdapter dataAdapter = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", connectionString);
DataSet myDataSet = new DataSet();
dataAdapter.Fill(myDataSet, "BookInfo");
DataTable dataTable = myDataSet.Tables["BookInfo"];
var rows = from p in dataTable.AsEnumerable()
where p[0].ToString() != null || p[0].ToString() != "" && p.Field<string>("F2") != null
select new
{ countryName= p[0],
bookCode= p.Field<string>("F2"),
bookName= p.Field<string>("F3")
};
The code above is not good as to get the “Code” I am using “ F2” and for country I am using p[0].What should I use to get the code and name for each country.
Also it’s give the information I want but I don't how to put in list or dictionary or in class so I can get data by passing parameter as a country name.
In short first it must put all data in list or dictionary and then you can call list or dictionary get data filter by country.
Thanks
There's two things you need to do:
First, you need to reformat the spreadsheet to have the column headers on the first row like the table below shows
| Country | Code | Name | IBN |
|---------|------|---------|------|
| Aust | UX | test1 | 34 |
| Aust | UZ | test2 | 345 |
| Aust | UN | test3 | 5654 |
| US | UX | name1 | 567 |
| US | TG | name2 | 123 |
| US | UM | name3 | 234 |
Second, use the Linq to Excel library to retrieve the data. It takes care of making the oledb connection and creating the sql for you. Below is an example of how easy it is to use the library
var book = new ExcelQueryFactory("pathToExcelFile");
var australia = from x in book.Worksheet()
where x["Country"] == "Aust"
select new
{
Country = x["Country"],
BookCode = x["Code"],
BookName = x["Name"]
};
Checkout the Linq to Excel intro video for more information about the open source project.
Suggestion 1
Checkout THIS link......as AKofC suggests, creating a class to hold your data would be your first port of call. The link I have posted has a small example of the sort of idea we are proposing.
Suggestion 2 with example...
The obvious thing to do from the code you have posted would be to create a new class to store your book information in.
Then you simply define which fields from your excel document it is that you want to pass into the new instance of your bookinformation class.
New Book Information Class:
class MyBookInfo
{
public string CountryName { get; set; }
public string BookCode { get; set; }
public string BookName { get; set; }
}
Method To Retrieve Info:
public void GetMyBookInfoFromExcelDocument()
{
string filename = #"C:\\" + "Book1.xls";
string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" + filename + ";" +
"Extended Properties=Excel 8.0;";
OleDbDataAdapter dataAdapter = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", connectionString);
DataSet myDataSet = new DataSet();
dataAdapter.Fill(myDataSet, "BookInfo");
DataTable dataTable = myDataSet.Tables["BookInfo"];
var rows = from p in dataTable.AsEnumerable()
where p[0].ToString() != null || p[0].ToString() != "" && p.Field<string>("F2") != null
select new MyBookInfo
{
CountryName = p.Field<string>("InsertFieldNameHere"),
BookCode = p.Field<string>("InsertFieldNameHere"),
BookName = p.Field<string>("InsertFieldNameHere")
};
}
From what I understand, I suggest creating a BookData class containing the properties you need, in this case Country, Code, Name, and IBN.
Then once you've filled your DataSet with the Excel stuff, create a new List, and loop through the DataRows in the DataSet adding the Excel values to the List.
Then you can use Linq on the List like so:
List<BookData> results = from books in bookList
where books.country == 'US'
select books;
Or something like that. I don't have Visual Studio on me, and Intellisense has spoiled me, so yeah. >__>

Resources