I want to make a simple Silverlight application in ASP.NET and LINQ. I have two talbe
Student :[student_id,student_name,address, phone,country_id] Country
:[country_id,country_name]
Thiw tow table is join by country_id.
I have inluced a LINQ Data Class in my project.
I have included a Silverlight-Enabled-WCF-Serfice. In this service I have made tow method and there code is like
[OperationContract]
public List<Country> LoadCountry()
{
var result = from coun in oLINQDataClassesDataContext.Countries
select coun;
return result.ToList();
}
[OperationContract]
public IList<Student> LoadStudent()
{
var result = from std in oLINQDataClassesDataContext.Students
select std;
return result.ToList();
}
Then I add a service reference of that WCF service. Then I include a DataGrid in my silverlight .xml file.
Now I want to show all the students in that DataGrid. For this I have written the following code
WCFServiceReference.WCFServiceClient oWCFServiceClient = new WCFServiceReference.WCFServiceClient();
public Home()
{
InitializeComponent();
oWCFServiceClient.LoadStudentCompleted += new EventHandler<WCFServiceReference.LoadStudentCompletedEventArgs>(oWCFServiceClient_LoadStudentCompleted);
oWCFServiceClient.LoadStudentAsync();
}
void oWCFServiceClient_LoadStudentCompleted(object sender, WCFServiceReference.LoadStudentCompletedEventArgs e)
{
dataGrid1.ItemsSource = e.Result;
}
Then I build the whole project and found no error. If I run the project then I found an error and it is--
An exception occurred during the operation, making the result invalid.
Check InnerException for exception details. at
System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()
at
Silverlight.WCFServiceReference.LoadStudentCompletedEventArgs.get_Result()
at Silverlight.Home.oWCFServiceClient_LoadStudentCompleted(Object
sender, LoadStudentCompletedEventArgse) at
Silverlight.WCFServiceReference.WCFServiceClient.OnLoadStudentCompleted(Object
state)
If I remove county table form the LINQ class and remove LoadCountry() method form the service and call LoadStudent() method form silverlight form then it runs accurately and all the data is displayed in my DataGrid.
If I remove student table form the LINQ class and remove LoadStudent() method form the service then LoadCountry() method runs accurately. Both methods are not work if the present same time in LINQ & WCF Service .
NB: Both tables has data. If I run a SQL join query then it returns data
I can’t understand what the problem is.
Is there anyone to help me regarding this problem?
Thanks in advance.
Rashed
go to properties of dbml file and change the Serialization mode to unidirectional
Related
Hello In my solution I've' got a class library named 'EntityFrameworkModel' AND here i add
ADO.NET ENTITY DATA MODEL. So my .edmx model perfectly created.
In my other project in this solution - which is asp,net project, in my web form here is what I do
I add the reference to my class library with the .edmx model
I add the
using EntityFrameworkModel ;directive
I make one really simple function
public void LoadTourists()
{
var db = new excursionEntities();
foreach (var tourist in db.Tourists)
{
lblproba.Text += tourist.Name_kir.ToString();
}
}
which I call on page_Load.
But I keep getting the above error
I have a webforms project, and am attempting to run some code that allows me to make a call to an MVC route and then render the result within the body of the web forms page.
There are a couple of HttpResponse/Request/Context wrappers which I use to execute a call to an MVC route, e.g.:
private static string RenderInternal(string path)
{
var responseWriter = new StringWriter();
var mvcResponse = new MvcPlayerHttpResponseWrapper(responseWriter, PageRenderer.CurrentPageId);
var mvcRequest = new MvcPlayerHttpRequestWrapper(Request, path);
var mvcContext = new MvcPlayerHttpContextWrapper(Context, mvcResponse, mvcRequest);
lock (HttpContext.Current)
{
new MvcHttpHandlerWrapper().PublicProcessRequest(mvcContext);
}
...
The code works fine for executing simple MVC routes, for e.g. "/Home/Index". But I can't specify any query string parameters (e.g. "/Home/Index?foo=bar") as they simply get ignored. I have tried to set the QueryString directly within the RequestWrapper instance, like so:
public class MvcPlayerHttpRequestWrapper : HttpRequestWrapper
{
private readonly string _path;
private readonly NameValueCollection query = new NameValueCollection();
public MvcPlayerHttpRequestWrapper(HttpRequest httpRequest, string path)
: base(httpRequest)
{
var parts = path.Split('?');
if (parts.Length > 1)
{
query = ExtractQueryString(parts[1]);
}
_path = parts[0];
}
public override string Path
{
get
{
return _path;
}
}
public override NameValueCollection QueryString
{
get
{
return query;
}
}
...
When debugging I can see the correct values are in the "request.QueryString", but the values never get bound to the method parameter.
Does anyone know how QueryString values are used and bound from an http request to an MVC controller action?
It seems like the handling of the QueryString value is more complex than I anticipated. I have a limited knowledge of the internals of the MVC Request pipeline.
I have been trying to research the internals myself and will continue to do so. If I find anything I will update this post appropriately.
I have also created a very simple web forms project containing only the code needed to produce this problem and have shared it via dropbox: https://www.dropbox.com/s/vi6erzw24813zq1/StackMvcGetQuestion.zip
The project simply contains one Default.aspx page, a Controller, and the MvcWrapper class used to render out the result of an MVC path. If you look at the Default.aspx.cs you will see a route path containing a querystring parameter is passed in, but it never binds against the parameter on the action.
As a quick reference, here are some extracts from that web project.
The controller:
public class HomeController : Controller
{
public ActionResult Index(string foo)
{
return Content(string.Format("<p>foo = {0}</p>", foo));
}
}
The Default.aspx page:
protected void Page_Load(object sender, EventArgs e)
{
string path = "/Home/Index?foo=baz";
divMvcOutput.InnerHtml = MvcWrapper.MvcPlayerFunctions.Render(path);
}
I have been struggling with this for quite a while now, so would appreciate any advice in any form. :)
MVC framework will try to fill the values of the parameters of the action method from the query string (and other available data such as posted form fields, etc.), that part you got right. The part you missed is that it does so by matching the name of the parameter with the value names passed in. So if you have a method MyMethod in Controller MyController with the signature:
public ActionResult MyMethod(string Path)
{
//Some code goes here
}
The query string (or one of the other sources of variables) must contain a variable named "Path" for the framework to be able to detect it. The query string should be /MyController/MyMethod?Path=Baz
Ok. This was a long debugging session :) and this will be a long response, so bear with me :)
First how MVC works. When you call an action method with input parameters, the framework will call a class called "DefaultModelBinder" that will try and provide a value for each basic type (int, long, etc.) and instance of complex types (objects). This model binder will depend on something called the ValueProvider collection to look for variable names in query string, submitted forms, etc. One of the ValueProviders that interests us the most is the QueryStringValueProvider. As you can guess, it gets the variables defined in the query string. Deep inside the framework, this class calls HttpContext.Current to retrieve the values of the query string instead of relying on the ones being passed to it. In your setup this is causing it to see the original request with localhost:xxxx/Default.aspx as the underlying request causing it to see an empty query string. In fact inside the Action method (Bar in your case) you can get the value this.QueryString["variable"] and it will have the right value.
I modified the Player.cs file to use a web client to make a call to an MVC application running in a separate copy of VS and it worked perfectly. So I suggest you run your mvc application separately and call into it and it should work fine.
I am making a very simple Lightswitch project which will connect to a table I have in an Oracle 11g database. I add an editable grid to the project and build the project. When I try to add or edit data in the grid I get the following error:
An error occurred while starting a transaction on the provider connection. See the inner exception for details.
Inner exception message:
Connection is already part of a local or a distributed transaction
There is no custom code in the project. My perception was that Lightswitch was supposed to make forms over data very easy. I've looked around for help but nothing so far.
//You need to clean up or the txn will fail..
partial void SaveChanges_Executed()
{
tx.Complete();
tx.Dispose();
}
If you get this error, "Inner exception message: Connection is already part of a local or a distributed transaction"
you can resolve the issue by following the second post by BScholz, https://forums.oracle.com/forums/thread.jspa?threadID=2263095
Basically, you need to implement SaveChanges_Excuting and SaveChanges_Excuted for the Oracle Data Source.
Switch to "File View" (LightSwitch will display "Logical View" by default).
Add a reference to "System.Transactions" in Server project.
Switch back to "Logical View"
Right Click the Data Source Name and click "View Code" to edit partial class.
Copy-and-paste the code below:
private TransactionScope _tscope;
partial void SaveChanges_Executing()
{
_tscope = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions
{
IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted
});
}
partial void SaveChanges_Executed()
{
_tscope.Complete();
_tscope.Dispose();
}
Try adding this code to your datasource code. (right click on the Oracle datasource and choose "View Code")
Make sure you remember to change the class name to match your datasource.
using System.Transactions;
namespace LightSwitchApplication
{
public partial class <ChangeThisToYourClassName>
{
private TransactionScope tx;
partial void SaveChanges_Executed()
{
tx.Complete();
}
partial void SaveChanges_Executing()
{
tx = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions {
IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted
});
}
}
}
I've been getting several errors:
cannot add an entity with a key that is already in use
An attempt has been made to attach or add an entity that is not new, perhaps having been loaded from another datacontext
In case 1, this stems from trying to set the key for an entity versus the entity. In case 2, I'm not attaching an entity but I am doing this:
MyParent.Child = EntityFromOtherDataContext;
I've been using using the pattern of wrap everything with a using datacontext. In my case, I am using this in a web forms scenario, and obviously moving the datacontext object to a class wide member variables solves this.
My questions are thus 2 fold:
How can I get rid of these errors and not have to structure my program in an odd way or pass the datacontext around while keeping the local-wrap pattern? I assume I could make another hit to the database but that seems very inefficient.
Would most people recommend that moving the datacontext to the class wide scope is desirable for web pages?
Linq to SQL is not adapted to disconnected scenarios. You can copy your entity to a DTO having a similar structure as the entity and then pass it around. Then copy the properties back to an entity when it's time to attach it to a new data context. You can also deserialize/reserialize the entity before attaching to a new data context to have a clean state. The first workaround clearly violates the DRY principle whereas the second is just ugly. If you don't want to use any of these solution the only option left is to retrieve the entity you're about to modify by its PK by hitting the DB. That means an extra query before every update. Or use another ORM if that's an option for you. Entity Framework 4 (included with .NET 4) with self-tracking entities is what I'm using currently on a web forms project and everything is great so far.
DataContext is not thread-safe and should only be used with using at the method level, as you already do. You can consider adding a lock to a static data context but that means no concurrent access to the database. Plus you'll get entities accumulated in memory inside the context that will turn into potential problems.
For those that came after me, I'll provide my own take:
The error "an attempt has been made to add or attach an entity that is not new" stems from this operation:
Child.Parent = ParentEntityFromOtherDataContext
We can reload the object using the current datacontext to avoid the problem in this way:
Child.Parent = dc.Entries.Select(t => t).Where(t => t.ID == parentEntry.ID).SingleOrDefault();
Or one could do this
MySubroutine(DataContext previousDataContext)
{
work...
}
Or in a web forms scenario, I am leaning to making the DataContext a class member such as this:
DataContext _dc = new DataContext();
Yes, the datacontext is suppose to represent a unit of work. But, it is a light-weight object and in a web forms scenario where a page is fairly transient, the pattern can be changed from the (using dc = new dc()) to simply using the member variable _dc. I am leaning to this last solution because it will hit the database less and require less code.
But, are there gotchas to even this solution? I'm thinking along the lines of some stale data being cached.
What I usually do is this
public abstract class BaseRepository : IDisposable
{
public BaseRepository():
this(new MyDataContext( ConfigurationManager.ConnectionStrings["myConnection"].ConnectionString))
{
}
public BaseRepository(MyDataContext dataContext)
{
this.DataContext = dataContext;
}
public MyDataContext DataContext {get; set;}
public void Dispose()
{
this.DataContext.Dispose();
}
}
Then imagine I have the following repository
public class EmployeeRepository : BaseRepository
{
public EmployeeRepository():base()
{
}
public EmployeeRepository(MyDataContext dataContext):base(dataContext)
{
}
public Employee SelectById(Guid id)
{
return this.DataContext.Employees.FirstOrDefault(e=>e.Id==id);
}
public void Update(Employee employee)
{
Employee original = this.Select(employee.Id);
if(original!=null)
{
original.Name = employee.Name;
//others
this.DataContext.SubmitChanges();
}
}
}
And in my controllers (I am using asp.net mvc)
public ActionResult Update(Employee employee)
{
using(EmployeeRepository employeeRepository = new EmployeeRepository())
{
if(ModelState.IsValid)
{
employeeRepository.Update(employee);
}
}
//other treatment
}
So the datacontext is properly disposed and I can use it across the same instance of my employee repository
Now imagine that for a specific action I want the employee's company to be loaded (in order to be displyed in my view later), I can do this:
public ActionResult Select(Guid id)
{
using(EmployeeRepository employeeRepository = new EmployeeRepository())
{
//Specifying special load options for this specific action:
DataLoadOptions options = new DataLaodOptions();
options.LoadWith<Employee>(e=>e.Company);
employeeRepository.DataContext.LoadOptions = options;
return View(employeeRepository.SelectById(id));
}
}
Since there is no ErrorProvider class in .NETCF, how can I implement similar functionality (not necessarily exactly like ErrorProvider)?
I am using all the regular databinding constructs to bind controls to a datatable, using the DataRow.RowError property and DataRow.SetColumnError method, but I can't find events on any of DataTable, BindingManagerBase, etc. that I can hook into to receive any sort of notification.
Am I stuck calling a method to manually iterate through all the controls on my form and change some look/feel of the bound control?
Thanks,
MrB
The ErrorProvider class seems pretty basic - actually, a little too basic. If you have Red Gate Reflector, I would recommend disassembling the class and looking at it. Otherwise, create a Dictionary<Control, String>.
Here is a quick idea on creating your own provider:
Dictionary<Control, String> ErrorSet = new Dictionary<Control, String>();
public void SetError(Control control, String message)
{
// code for adding error information
ErrorSet.Add(control, message);
}
public String GetError(Control control)
{
// code for retrieving error information
return ErrorSet[control];
}
public String Clear()
{
// code for clearing all errors
}
I don't have R-G reflector here or I would provide more sample methods. But this ought to provide some sort of sample to work from.