z488758
asked on
c# LINQ to SQL and proper procedure
Hi
I would like please a LINQ to SQL expert to comment. I am using LINQ to SQL but it appears to me that itis not an effecive way to communicate to the database, but perhaps it is the way that I am doing it.
Firstly I have a datacontext class as follows
#region DataContext
public class TQ : DataContext
{
public static string ConnectionString = "Password=74XXX;Persist Security Info=True;User ID=questuser;Initial Catalog=Tradequest; Data Source=LIVESERVER";
private static readonly string connString = ConnectionString;
public TQ()
: base(connString)
{ }
}
#endregion
then in each method I opent that context as per the following small method example (I hve defined the class seperately)
public static int GetUniqueId(int marketId, int selectionId)
{
int rt = 0;
using (TQ contextRO = new TQ())
{
Table<clsRunnersWithTrades > tblRunnersWithTrades = contextRO.GetTable<clsRunn ersWithTra des>();
try
{
var updateRunner = (from r in tblRunnersWithTrades where r.Marketid == marketId && r.Selectionid == selectionId select r).FirstOrDefault();
if (updateRunner != null)
rt = updateRunner.id;
}
catch (Exception ex) { LogAuditRecord("GE", "General error User functions : " + ex.ToString()); }
return rt;
}
}
Where thi all seem to struggle for me is
(a) at the point where the execution is triggered (deferred or non) the table command has it load all the table records. If I look at the table line, if there is 100,000 records in the table it will load all 100000 records, with the var command then pulling a subset from this. That does not seem efficient when I only want one of several recordsin the dataset?
(b) I have constantly battled concurrency errors when using threading, such that I have had to put an (UpdateCheck = UpdateCheck.Never) command into the definong of the class.
Surely there is something I am doing that is not quite right, and guidance or ideas would be appreciated. If tht is ditch LINQ and drop back to datasets and sprocs then happy to recieve that advice also
Thanks
I would like please a LINQ to SQL expert to comment. I am using LINQ to SQL but it appears to me that itis not an effecive way to communicate to the database, but perhaps it is the way that I am doing it.
Firstly I have a datacontext class as follows
#region DataContext
public class TQ : DataContext
{
public static string ConnectionString = "Password=74XXX;Persist Security Info=True;User ID=questuser;Initial Catalog=Tradequest; Data Source=LIVESERVER";
private static readonly string connString = ConnectionString;
public TQ()
: base(connString)
{ }
}
#endregion
then in each method I opent that context as per the following small method example (I hve defined the class seperately)
public static int GetUniqueId(int marketId, int selectionId)
{
int rt = 0;
using (TQ contextRO = new TQ())
{
Table<clsRunnersWithTrades
try
{
var updateRunner = (from r in tblRunnersWithTrades where r.Marketid == marketId && r.Selectionid == selectionId select r).FirstOrDefault();
if (updateRunner != null)
rt = updateRunner.id;
}
catch (Exception ex) { LogAuditRecord("GE", "General error User functions : " + ex.ToString()); }
return rt;
}
}
Where thi all seem to struggle for me is
(a) at the point where the execution is triggered (deferred or non) the table command has it load all the table records. If I look at the table line, if there is 100,000 records in the table it will load all 100000 records, with the var command then pulling a subset from this. That does not seem efficient when I only want one of several recordsin the dataset?
(b) I have constantly battled concurrency errors when using threading, such that I have had to put an (UpdateCheck = UpdateCheck.Never) command into the definong of the class.
Surely there is something I am doing that is not quite right, and guidance or ideas would be appreciated. If tht is ditch LINQ and drop back to datasets and sprocs then happy to recieve that advice also
Thanks
Need to understand what are you trying to achieve then only can we suggest a solution
ASKER
Thanks.
All I want is to efficienetly communicate to the database. I have an application that is adding to or interogating the database. Simple requirement, about 10 tables, no associations between tables, maybe 100,000 records in 1 or 2 tables, only in the thousands in the others. I simply want to add records or update values in the master file table, as quickly as possible
All I want is to efficienetly communicate to the database. I have an application that is adding to or interogating the database. Simple requirement, about 10 tables, no associations between tables, maybe 100,000 records in 1 or 2 tables, only in the thousands in the others. I simply want to add records or update values in the master file table, as quickly as possible
Linq is always deferred until needed. You're right that it's going to grab everything, then take what it needs. Nothing is faster than straight ADO.NET when you want to talk to a database.
Also, if everything is forward-only and take once/write once for distribution to other tables then I wouldn't even mess with data sets... I would just use data readers. If each row has potentially more than one target the I would use data tables/datasets.
Also, if everything is forward-only and take once/write once for distribution to other tables then I wouldn't even mess with data sets... I would just use data readers. If each row has potentially more than one target the I would use data tables/datasets.
Hi z488758;
The following line in your code will load the complete table from the database to your local system. Unless you need to do the processing on your system do not do this.
Table<clsRunnersWithTrades > tblRunnersWithTrades = contextRO.GetTable<clsRunn ersWithTra des>();
To your question, "That does not seem efficient when I only want one of several recordsin the dataset?", you are correct the above line should be removed. See snippet below:
To your question marked as (b), how are you using the DataContect one for multiple threads? more info would be needed.
Fernando
The following line in your code will load the complete table from the database to your local system. Unless you need to do the processing on your system do not do this.
Table<clsRunnersWithTrades
To your question, "That does not seem efficient when I only want one of several recordsin the dataset?", you are correct the above line should be removed. See snippet below:
public static int GetUniqueId(int marketId, int selectionId)
{
int rt = 0;
using (TQ contextRO = new TQ())
{
try
{
var updateRunner = (from r in contextRO.clsRunnersWithTrades
where r.Marketid == marketId && r.Selectionid == selectionId
select r).FirstOrDefault();
if (updateRunner != null)
rt = updateRunner.id;
}
catch (Exception ex)
{
LogAuditRecord("GE", "General error User functions : " + ex.ToString());
}
return rt;
}
}
To your question marked as (b), how are you using the DataContect one for multiple threads? more info would be needed.
Fernando
ASKER
Fetnando
Thanks for the comment on not seperately initialising the table, that is valuable and I will adopt thanks. As far as the datacontext, as I am opening within each method, then each thread will open once of in some cases multiple times. I have not attempted to hold a datacontext open, thinking that that would only exacerbate the table problem, as the using statement was atleast disposing of the table. Given the above change you have suggested, should I use one datacontext, or one context per thread and if so if you could point me in the right direction as the best way to make available across multiple threads would be appreciated
Thanks very much for your help
Ian
Thanks for the comment on not seperately initialising the table, that is valuable and I will adopt thanks. As far as the datacontext, as I am opening within each method, then each thread will open once of in some cases multiple times. I have not attempted to hold a datacontext open, thinking that that would only exacerbate the table problem, as the using statement was atleast disposing of the table. Given the above change you have suggested, should I use one datacontext, or one context per thread and if so if you could point me in the right direction as the best way to make available across multiple threads would be appreciated
Thanks very much for your help
Ian
Hi Ian;
This article on DataContext Lifecycle should answer you question. Rick Strahl has done a great job and more then I can do here.
Linq to SQL DataContext Lifetime Management
http://www.west-wind.com/w eblog/post s/246222.a spx
Fernando
This article on DataContext Lifecycle should answer you question. Rick Strahl has done a great job and more then I can do here.
Linq to SQL DataContext Lifetime Management
http://www.west-wind.com/w
Fernando
ASKER
Fernando
Thanks for your comments. In your suggestion not to initialise the table but call it directly in the linq command, I can't see the table in the command. That is,
contextRO.clsRunnersWithTr ades
does not see the "clsRunnersWithTrades". Can you think of something in the initialisation of the context class or similar that would stop the class from being called from the contactas you have suggested?
Thanks
Ian
Thanks for your comments. In your suggestion not to initialise the table but call it directly in the linq command, I can't see the table in the command. That is,
contextRO.clsRunnersWithTr
does not see the "clsRunnersWithTrades". Can you think of something in the initialisation of the context class or similar that would stop the class from being called from the contactas you have suggested?
Thanks
Ian
Hi z488758;
In your original code you had this line of code.
Which creates a table of type clsRunnersWithTrades in the model that maps to a table in the store / database by the same name if you did not change it in the DBML file / model. So removing that line of code and just using the query to fill with only the filtered records you only need the following:
Should be accessing the same table. Now if you have your IDE set up to do pluralization of name then a table in the database lets say Customers would become Customer in the Model. So this name clsRunnersWithTrades could be clsRunnersWithTrade in the model.
If you are still having issues with this please post the code of the DBML file here.
Fernando
In your original code you had this line of code.
Table<clsRunnersWithTrades> tblRunnersWithTrades = contextRO.GetTable<clsRunnersWithTrades>();
Which creates a table of type clsRunnersWithTrades in the model that maps to a table in the store / database by the same name if you did not change it in the DBML file / model. So removing that line of code and just using the query to fill with only the filtered records you only need the following:
var updateRunner = (from r in contextRO.clsRunnersWithTrades
where r.Marketid == marketId && r.Selectionid == selectionId
select r).FirstOrDefault();
Should be accessing the same table. Now if you have your IDE set up to do pluralization of name then a table in the database lets say Customers would become Customer in the Model. So this name clsRunnersWithTrades could be clsRunnersWithTrade in the model.
If you are still having issues with this please post the code of the DBML file here.
Fernando
ASKER
Thanks Fernando.
Intellisense when typing (from r in contextRO. does not see any classes.
I did not use the designed to create the mapping but did it manually as per the attached.
Your help is very much appreciated
Ian
Intellisense when typing (from r in contextRO. does not see any classes.
I did not use the designed to create the mapping but did it manually as per the attached.
Your help is very much appreciated
Ian
[Table(Name = "tblRunnersWithTrades")]
public class clsRunnersWithTrades
{
[Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "int Not Null IDENTITY")] public int id;
[Column] public int Marketid;
[Column] public int Selectionid;
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanksyou Fernando, you are spot on, that has fixed it, thankyou for your first class support and advice
Ian
Ian
Not a problem Ian; glad I was able to help.