I am using linq-to-entity to retrieve data dynamically and created a method as follows:
public List<object> getDynamicList(string tablename, List<string> colnames)
{
try
{
var query = DynamicQueryable.getDynamicData(dbcontext, tablename, colnames);
List<object> objQueryable = new List<object>();
object obj = query.AsQueryable();
objQueryable.Add(obj);
return objQueryable;
}
catch (Exception ex)
{
HandleError(ex);
}
}
this method in wcf service internally refers dynamic class given in LINQ samples (C:\Program Files (x86)\Microsoft Visual Studio 10.0\Samples\1033)by MSVS2010.
when i am passing tablename,columns dynamically it does but on client side,while consuming that method it gives error- The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
does wcf gives issue with iqueryable return type ?
please suggest......
You should look into WCF Data Services aka oData Services
Try using returning ToList() instead because Linq uses concept of Deffer Loading which means when at client side ToList or Result is being accessed it tries to connect to Server for getting result and it is where it would be getting failed. It is recommended when you use such kind of ORM you detach your objects and send result to client.
Related
I have a .NET web application that frequently executes queries to get data from a local database.
In situations where the query doesn't run (due to an exception) or the query returns an unexpected set of data (such as an empty set). I want to be able to rebuild the query (replacing it's #parameters with the values actually used) and store the complete query in the database along with the exception.
I'm aware that I can do this through standard code but I was wondering whether it would be safer to do via Elmah?
Also would doing this via Elmah give me the ability to be able to view the executed sql through elmah.axd (when access is enabled)?
Unless the thrown exception includes the query with the actual values, ELMAH doesn't help you there other than logging the exception. You can catch the exception yourself and do a custom logging to ELMAH using the ErrorSignal.Raise method as explained here: How to use ELMAH to manually log errors?
I log SQL exceptions by passing the exception and the actual command to a new Exception class. The class wraps the SqlException and the System.Data.Common.DbCommand objects. Using that information I can create a message to provide the sql command details:
public override string Message
{
get
{
StringBuilder message = new StringBuilder("");
StringBuilder sql = new StringBuilder("");
sql.AppendFormat(" {0} ", Command.CommandText);
foreach (SqlParameter param in Command.Parameters)
{
sql.AppendFormat(" {0} - {1}", param.ParameterName,
param.Value.ToString());
}
message.AppendFormat("Error: {0} SQL: {1} User: {2}", SqlEx.Message,
sql, Username);
return message.ToString();
}
}
Finally, I use the ErrorSignal Raise method to log the message in Elmah:
Elmah.ErrorSignal.FromCurrentContext().Raise(new DetailSqlException(e.Exception as SqlException, e.Command, user));
I'm dipping my foot into WCF and am trying to make a simple test project that can both consume the service as a service and also directly instantiate it's classes and work with them.
I had an earlier working version where data passed was just primitive types. However, when I attempted to convert to using data contracts, I'm getting conflicts in whether it's referencing the proxy-declared version of the contract or the version from the project itself.
Question: Is it possible to do this and if so, how would I resolve the data contract references?
private void Test()
{
MyService fssDirect = new MyService(); // direct instantiation
MyServiceClient fssService = new MyServiceClient(); // Service proxy
ClientCredentialsContract Client = new ClientCredentialsContract();
ResponseDataContract Result = new ResponseDataContract();
if (CallAsService)
{
Result = fssService.Create(Client, Request);
}
else
{
Result = fssDirect.Create(Client, Request);
}
}
In the above, any reference to the RequestDataContract and ClientCredentialsContract types indicates
Warning: The type 'MyContracts.RequestDataContract' in 'C:...\Test\MyServiceProxy.cs' conflicts with the imported type 'MyContracts.RequestDataContract' in 'C:...\MyService\bin\Debug\Contracts.dll'. Using the type defined in 'C:...\Test\MyServiceProxy.cs'.
(Names changed and paths shortened to protect the innocent)
Thanks,
John
When you create the proxy for your service, try referencing the assembly which contains the data contracts (if using "Add Service Reference", go to the advanced options, select "reuse types in referenced assemblies"; if using svcutil, use the /r argument). This way the tool won't generate the data contracts and you won't have the conflicts.
I am working on WCF Data service which imported stored procedure, as below.
[WebGet]
public List<GetMTSearchResultTest_Result> GettMTSearchResultTest()
{
MediaMarketResearch_PRODEntities ent = new MediaMarketResearch_PRODEntities();
return ent.GetMTSearchResultTest().ToList();
}
when i consuming this in my client application it says error as "The closed type MMRClient.MMRServiceReference.GetMTSearchResultTest_Result does not have a corresponding element settable property."
I am getting this error while bind to the grid view as below.
DataServiceContext context = new DataServiceContext(new Uri("http://localhost:4131/MMRDataService.svc/"));
IEnumerable<GetMTSearchResultTest_Result> empResult = context.Execute<GetMTSearchResultTest_Result>(new Uri("http://localhost:4131/MMRDataService.svc/GettMTSearchResultTest"));
GridView1.DataSource = empResult;
GridView1.DataBind();
Note: I imported this stored proc as complex type.
Please advice me on this.
Regards,
Jaydeep
I think this link may help you (see the selected answer).
Essentially, what the solution may be is to create a partial class for GetMTSearchResultTest_Result and decorate it with a DataServiceKey attribute, providing a non-nullable column that acts as a primary key (although I don't think it has to be unique).
So your partial class would look something like:
[DataServiceKey("YourKeyColumnName")]
public partial class GetMTSearchResultTest_Result {
}
If you're just doing reads, I don't think you'll need any implementation.
Hopefully this works. Let me know if there are issues/questions and I'll update accordingly.
You can always make a new service reference to a non data service. That is to a normal WCF service. You can simply have a [ContractOperation] returning a list of the troubled "complex types" and that's it.
This way you would have two services the original data service and a new normal WCF service. But this shouldn't be such an issue. You don't have to make the troubled "complex type" as a Entity.
We have a situation where we have multiple databases with identical schema, but different data in each. We're creating a single session factory to handle this.
The problem is that we don't know which database we'll connect to until runtime, when we can provide that. But on startup to get the factory build, we need to connect to a database with that schema. We currently do this by creating the schema in an known location and using that, but we'd like to remove that requirement.
I haven't been able to find a way to create the session factory without specifying a connection. We don't expect to be able to use the OpenSession method with no parameters, and that's ok.
Any ideas?
Thanks
Andy
Either implement your own IConnectionProvider or pass your own connection to ISessionFactory.OpenSession(IDbConnection) (but read the method's comments about connection tracking)
The solution we came up with was to create a class which manages this for us. The class can use some information in the method call to do some routing logic to figure out where the database is, and then call OpenSession passing the connection string.
You could also use the great NuGet package from brady gaster for this. I made my own implementation from his NHQS package and it works very well.
You can find it here:
http://www.bradygaster.com/Tags/nhqs
good luck!
Came across this and thought Id add my solution for future readers which is basically what Mauricio Scheffer has suggested which encapsulates the 'switching' of CS and provides single point of management (I like this better than having to pass into each session call, less to 'miss' and go wrong).
I obtain the connecitonstring during authentication of the client and set on the context then, using the following IConnectinProvider implementation, set that value for the CS whenever a session is opened:
/// <summary>
/// Provides ability to switch connection strings of an NHibernate Session Factory (use same factory for multiple, dynamically specified, database connections)
/// </summary>
public class DynamicDriverConnectionProvider : DriverConnectionProvider, IConnectionProvider
{
protected override string ConnectionString
{
get
{
var cxnObj = IsWebContext ?
HttpContext.Current.Items["RequestConnectionString"]:
System.Runtime.Remoting.Messaging.CallContext.GetData("RequestConnectionString");
if (cxnObj != null)
return cxnObj.ToString();
//catch on app startup when there is not request connection string yet set
return base.ConnectionString;
}
}
private static bool IsWebContext
{
get { return (HttpContext.Current != null); }
}
}
Then wire it in during NHConfig:
var configuration = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2005
.Provider<DynamicDriverConnectionProvider>() //Like so
In SQL Server 2005, is there a way to specify more than one connection string from within a .NET Application, with one being a primary preferred connection, but if not available it defaults to trying the other connection (which may be going to a diff DB / server etc)?
If nothing along those exact lines, is there anything we can use, without resorting to writing some kind of round-robin code to check connections?
Thanks.
We would typically use composition on our SqlConnection objects to check for this. All data access is done via backend classes, and we specify multiple servers within the web/app.config. (Forgive any errors, I am actually writing this out by hand)
It would look something like this:
class MyComponent
{
private SqlConnection connection;
....
public void CheckServers()
{
// Cycle through servers in configuration files, finding one that is usable
// When one is found assign the connection string to the SqlConnection
// a simple but resource intensive way of checking for connectivity, is by attempting to run
// a small query and checking the return value
}
public void Open()
{
connection.Open();
}
public ConnectionState State
{
get {return connection.State;}
set {connection.State = value;}
}
// Use this method to return the selected connection string
public string SelectedConnectionString
{
get { return connection.ConnectionString; }
}
//and so on
}
This example includes no error checking or error logging, make sure you add that, so the object can optionally report which connections failed and why.
Assuming that you'd want to access the same set of data, then you'd use clustering or mirroring to provide high availability.
SQLNCLI provider supports SQL Server database mirroring
Provider=SQLNCLI;Data Source=myServer;Failover Partner=myMirrorServer
Clustering just uses the virtual SQL instance name.
Otherwise, I can't quite grasp why you'd want to do this...
Unfortunately there are no FCL methods that do this - you will need to implement this yourself.