I am writing a web service, using C# and Linq. I am fairly new to this, and using tutorials on line I have been able to do most everything I need. I have web services for a variety of complex operations on my database.
Where I have run into a problem is with adding records to my tables. I have followed a number of tutorials, which all seem very simple, but I have a reference that I am clearly missing and cannot find. I am using SQL Server (2008), and have built a WCF Service Library. The start of the code is:
public const int RET_OK = 0;
public const int RET_NOT_OK = -1;
public const int RET_TICKET_NO_SERVER = -1;
int retInt;
xxxxEntities3 xxxxDB = new xxxxEntities3();
public int CreateTicket(ref string strServer)
{
if ((strServer == null) || (strServer.Length == 0))
{
return(RET_TICKET_NO_SERVER);
}
ticket tick = new ticket();
tick.serveTime = DateTime.Now;
tick.server = strServer;
xxxxDB.tickets.AddObject(tick);
return (0);
}
I have made sure to add a reference to the System.Data.Linq assembly, and I have verified that the .edmx file is correct (all of my "reading" web services work great).
The problem is that when I try to insert changes (with something like this):
xxxxDB.tickets.SubmitChanges(tick);
I get that the SubmitChanges is not found (it asks if I am missing a reference). Am I? I am sure this is very simple, but I must be too tired - I just don't see it.
Thanks in advance!
Isn't SubmitChanged defined on at the root of the database layer? This is my experience with LinqToSql. For instance, you would manipulate things on a table by table basis, but push changes at once:
database.table.InsertOnSubmit(entity);
database.SubmitChanges();
Now, it looks like you're using a slightly different LinqToSomething mechanism that I'm not entirely familiar with - but many of the principles are not doubt shared.
As brought to attention by #Henk and #Kirk, there are a couple of things to consider here:
With EF, the call should apparently be on the context itself, as suggested
With EF, the call to make is SaveChanges as opposed to SubmitChanges
Related
How do i do this the proper way legit code. like if it do a linq query within using and the result is i want it to use on another different bracket of using another call of linq query
if i store it i could declare a pre define var neither can i use a class constructor method.
what is the proper way to do this that i may able to use it on maybe different modules or different function / method without again doing the same call over in every method.
Hope i made it clear what i want.
var globalstorage;
using (Si360DbContext _si360DbContext = new Si360DbContext())
{
var selectedItems = _si360DbContext.SaleDumpDetails
.Where(sd => sd.SaleID == saleid)
.Select(i => i.SaleItemID).ToList();
//Store data..
globalstorage = selectedItems;
}
// able to reuse it else where having the same data stored on it.
globalstorage
It depends... as always...
If you're working on a web project, some mechanism that allows you to cache would be approprate. A MemoryCache for example could be a good and fast solution. However... If the amount of data grows, or you run multiple instances of the same website for example, you may need a distributed cache system like Redis.
For different types of apps, console or maybe Windows desktop you could just create a public static variable and you're good to go. So again, it totally depends on the needs of your solution.
I am using Dapper Extensions (DE) as ORM. It is consumed in Data Access Layer which is implemented using Repository pattern. SQL Express is back-end RDBMS.
DE automatically generates most of the queries for me. I want to log those auto-generated queries for debugging purpose.
There are two ways I can see to achieve this: -
Get the SQL query generated by DE (before or after it is executed) and write it to log. This is preferred way for me as I already have my logging module (using log4net) in place. The only thing I need is the SQL generated by DE.
Integrate DE with some logging tool. I read this answer. It looks possible using MiniProfiler tool; but as I said above, I already have my logging module in place. I do not want to use other tool just for logging SQL queries.
How to log/get a SQL query auto-generated by Dapper Extensions without using any other logging tool?
The other similar question is about Dapper. This question is about Dapper Extensions.
Looking at the comment from #MarcGravell and this question about doing the same with Dapper, MiniProfiler.Integrations is better way to implement logging for Dapper Extensions.
Above linked question is about Dapper. But Dapper Extensions uses Dapper internally. So, if logging is implemented for Dapper, same works for Dapper Extensions as well.
More details could be found on GitHub.
Sample code is as below:
var factory = new SqlServerDbConnectionFactory(connectionString);
CustomDbProfiler cp = new CustomDbProfiler();
using(var connection = DbConnectionFactoryHelper.New(factory, cp))
{
//DB Code
}
string log = cp.ProfilerContext.GetCommands();
You can use in-build CustomDbProfiler using CustomDbProfiler.Current if that suits your need. cp.ProfilerContext.GetCommands() will return ALL the commands (success and failed) no matter how many times you call the method. I am not sure but, it might be maintaining concatenated string (StringBuilder may be) internally. If this is the case, this may slow down the performance. But, in my case, logging is disabled by default. I only enable logging when I need to debug something. So this is not a problem for me.
This also may raise memory footprint issue if single connection is used over very large scope. To avoid this, make sure CustomDbProfiler instance is disposed properly.
As mentioned in question, initially, I wanted to avoid this way (using external tool/library). But, MiniProfiler.Integrations is NOT writing the log itself. I can simply get all the queries generated and provide those to my logger module to dump into the file. That is why, this looks more suitable to me now.
MiniProfiler.dll internally implements similar logic (in StackExchange.Profiling.Data.ProfiledDbConnection and StackExchange.Profiling.Data.ProfiledDbCommand classes) which is mentioned here and here. So, if I decide to (in future may be) bypass MiniProfiler, I can use this implementation myself.
Dapper Extensions project is open source; everyone knows that. I downloaded it from GitHub and modified it to meet my needs.
Dapper Extensions build/generate SQL query internally in SqlGeneratorImpl class. There are multiple methods in this class those generate the various queries.
I added following property in DapperExtensions.DapperExtensions static class:
static string lastGeneratedQuery;
public static string LastGeneratedQuery
{
get
{
lock(_lock)
{
return lastGeneratedQuery;
}
}
internal set
{
lock(_lock)
{
lastGeneratedQuery = value;
}
}
}
Also, set this property in various methods of SqlGeneratorImpl class. Following is an example how I set it in Select method.
public virtual string Select(IClassMapper classMap, IPredicate predicate, IList<ISort> sort, IDictionary<string, object> parameters)
{
......
......
StringBuilder sql = new StringBuilder(string.Format("SELECT {0} FROM {1}",
......
......
DapperExtensions.LastGeneratedQuery = sql.ToString();
return sql.ToString();
}
Basic tests run well; I have not yet tested this thoroughly. I will update this answer in case of any change.
Please note that I do not recommend this as standard solution; this is just a hack that works for my needs. I would really like to see this as a regular feature in library. Please post an answer if you have better solution. Otherwise, please comment to improve the solution suggested here.
After merging this pull request in master branch, hopefully this is now available out of the box and no need to download and modify the toolkit source code anymore. Note that I have not verified this.
I'm very newbie in MVC 4 and Entity-Framework
If this question does not make sense, please let me explain better.
During the example I'm working on, I have noticed that I can make an insertion to database either using AddObject or AddToMyTableName.(my specific table name which is exist in database)
So I'm kinda confused what is the difference between these?
And which one I should use in what cases?
Here is very simplified example:
In the controller:
This is example for AddObject:
using (myProj.Models.myProjEntities db = new Models.myProjEntities())
{
myProj.Models.TestClass myTestClass = new myProj.Models.TestClass();
myTestClass.prop1 = "test1";
myTestClass.prop2 = "test2";
db.MyTable.AddObject(myTestClass);
db.SaveChanges();
}
And here is the example for AddToSpecificTable:
using (myProj.Models.myProjEntities db = new Models.myProjEntities())
{
myProj.Models.TestClass myTestClass = new myProj.Models.TestClass();
myTestClass.prop1 = "test1";
myTestClass.prop2 = "test2";
db.AddToMyTable(myTestClass);
db.SaveChanges();
}
Both of them are inserting the values to db and both are working same in my example. I'm pretty sure there are some cases when one of them is working , the other will not.
Can anyone please explain the difference?
Thanks
The AddTo<TEntity> method is now considered deprecated and has been used with EF4 and previous versions. With EF4.x the new AddObject() was introduced as replacement method for AddTo<TEntity> but for some (unknown) reason the AddTo<TEntity> method was still available even though it's was recommended to use the new AddObject() method. As of now, with EF5+ you can just use Add(). It's hard to find the exact reasons for the replacement of the methods but I guess this is most probably historical reasons and as the EF evolved so the methods were changed to reflect the new versions.
So if you consider why (if in any scenario) the one is better than the other, than just use the most common one (Of course if you don't have some version restrictions like, if you are using EF 4 for example). Otherwise you are not gaining anything and usually after some method is marked as deprecated sooner or later it's removed, so if you use AddTo<TEntity> you might need to rewrite parts of your code due to the fact that in some future version this method is no longer presented.
I have an asp.net 4.0 c# web application. I am using listview and formview controls with templates on my forms. I am trying to control the maxlength property of my bound textboxes without hard coding the field sizes into my aspx pages. I would like to when I first load the application fill some kind of local object or array with the column lengths of my fields and then use those values to dynamically set the maxLength field of textboxes.
There are so many methods out there to try and I am not sure what is the most efficient.
My sql to get the schema info is
SELECT TOP (100) PERCENT sys.sysobjects.name AS TableName, sys.syscolumns.name AS ColumnName, sys.systypes.name AS DataType,
sys.syscolumns.length
FROM sys.sysobjects INNER JOIN
sys.syscolumns ON sys.sysobjects.id = sys.syscolumns.id INNER JOIN
sys.systypes ON sys.syscolumns.xtype = sys.systypes.xtype WHERE (sys.sysobjects.xtype = 'U') AND (sys.systypes.name <> 'sysname')
ORDER BY TableName, sys.syscolumns.colid
how can i store this locally so I don't have to keep querying the server and I can I set this dynamically using c#
I am a semi newbie so as much detail as can be provided would be appreciated.
See you are getting the column lengths from the database, now you need to do this txtBox.MaxLength.
Doing this dynamically can be avoided if you already design your aspx pages tightly coupled with database tables.
But if you are sure you want to go this way then:
1.) On application start up fetch all the values from the DB and make a dictionary cache out of it, it will sit in memory as long as the application is up.
2.) Now, on each page load you need to read those values from the dictionary and use TextBox.MaxLength property to set the values. This way you are adjusting the max length property before it is delivered to the client machine.
Thats it !!!
Anyways, any approach of this sort will bring down application performance. Consider pre-designing aspx pages.
There are two main ways of doing this, static variables (essentially global variables) or using the application cache. Personally I prefer static variables as I find the API for System.Web.Caching to be over-complicated.
This is how you use static variables with a bit of a discussion on which is the best method (including how to use the new Lazy class in .Net 4.0+):
Why use System.Runtime.Caching or System.Web.Caching Vs static variables?
This is how to use System.Web.Caching:
http://msdn.microsoft.com/en-us/library/system.web.caching.cache.aspx
I wouldn't worry too much about which is more efficient, the methods of doing this are almost identical performance wise.
Thanks for your suggestions. For my purposes I just kept it simple because this is a relatively small app.
Since I am using templates I have the same field defined multiple times in many places. Since my application data fields will be changing not infrequently, this just gives me one place in the application to change the maxLength property.
in my aspx page:
' MaxLength="<%# TableSchema.SomeField1Length%>" />
I made a class
public static class TableSchema
{
public static int SomeField1Length
{
get { return 15; }
}
public static int SomeField2Length
{
get { return 100; }
}
public static int SomeField3Length
{
get { return 15; }
}
}
It's seems to be working ok. I have to see if this causes a performance hit.
I have been dealing with this for a couple weeks now, and figured it was time to bring someone else in. I have been to many sites trying to solve this, but I'll start from the beginning.
This is my first project in mvc and ef, so I have relied on a lot of tutorials.
I started with this one...
http://msdn.microsoft.com/en-us/data/gg699321.aspx
Everything else I find on the web pretty much just shows me the same things, so I figured this was pretty simple.
The stored procedure in question is pretty simple, it just returns a string from a table.
SELECT TOP 1 ConnectionString
FROM tConfig
WHERE Active = 1
I generated an edmx file, like in the article above, and it generated the following code in a context file. I have tried this both with, and without the EntityContainerName next to the procedure.
public virtual ObjectResult<string> psMasterDataSource()
{
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<string>("CentralApp.psMasterDataSource");
}
Where I am using it is also pretty simple.
public string GetMasterDSConn() {
var context = new CentralApp();
var conn = context.psMasterDataSource().SingleOrDefault();
return conn;
}
But when I run it, I get the following error.
The FunctionImport 'psMasterDataSource' could not be found in the container 'CentralApp'.
I saw someone on another site talked about editing the XML, but I couldn't find anything helpful on what to edit. So I am hoping I am missing something simple there.
I appreciate any help on this. I am ready to get this app tested, but this is holding me back.