Quantcast
Channel: WCF Data Services forum
Viewing all 877 articles
Browse latest View live

How do I use the WCF DS 5.5 EntityFrameworkDataServiceProvider?

$
0
0

So, I'm attempting to make use of the new public EntityFrameworkDataServiceProvider (EFDSP) in WCF Data Services 5.5. I created a subclass of EFDSP, and I'd like to use it in my DataService, but the constructor for the EFDSP class requires a DataServiceProviderArgs instance, which in turn requires a pointer to both the data service instance (I assume this is the DataService<T> subclass?), and a data source instance. My initial assumption was that I would modify my DataService<T> sub-class to implement IServiceProvider, and return the EFDSP instance. The problem is that, when WCF calls the GetService method of my DataService<T> sub-class, it hasn't yet called CreateDataSource. This means that, if I attempt to pass this.CurrentDataSource to EFDSP's constructor, I get a NullReferenceException. Do I create my data source early, within GetService, and just return the one I created in CreateDataSource? Or am I misunderstanding something about EFDSP?

Also, it seems EFDSP already implements IServiceProvider. Does this mean I have to forward the call over to the instance I create (assuming I can create one successfully)?




Performance issue in ODataJsonLightReader

$
0
0

Hi,

I have for some time been frustrated with the bad performance I am getting in WCF DS client code when running with the Json (light) format. Finally I did some profiling of the issue and here are my findings.

First of all my model is very large (around 400 entities with around 200 simple properties each on average and 100 reference properties).

When I do queries against my service wthout any projections and on the Json format the client will end up using 100% CPU resources and perform really bad. Doing a profilling of the client shows that around 90% of the time is spent in this function:

Function NameInclusive SamplesExclusive SamplesInclusive Samples %Exclusive Samples %Module Name
-Microsoft.Data.OData.JsonLight.ODataJsonLightReader.StartNavigationLink
102.4257592,230,07Microsoft.Data.OData.dll
-Microsoft.Data.Edm.Csdl.Internal.CsdlSemantics.CsdlSemanticsEntitySet.FindNavigationTarget
101.04141890,990,38Microsoft.Data.Edm.dll

IlSpy revaels the implementation of FindNavigationTarget to be something like:

public IEdmEntitySet FindNavigationTarget(IEdmNavigationProperty property)
{
	CsdlSemanticsNavigationProperty csdlSemanticsNavigationProperty = property as CsdlSemanticsNavigationProperty;
	if (csdlSemanticsNavigationProperty != null)
	{
		using (IEnumerator<IEdmEntityContainer> enumerator = this.Model.EntityContainers().GetEnumerator())
		{
			while (enumerator.MoveNext())
			{
				CsdlSemanticsEntityContainer csdlSemanticsEntityContainer = (CsdlSemanticsEntityContainer)enumerator.Current;
				IEnumerable<CsdlSemanticsAssociationSet> enumerable = csdlSemanticsEntityContainer.FindAssociationSets(csdlSemanticsNavigationProperty.Association);
				if (enumerable != null)
				{
					foreach (CsdlSemanticsAssociationSet current in enumerable)
					{
						CsdlSemanticsAssociationSetEnd csdlSemanticsAssociationSetEnd = current.End1 as CsdlSemanticsAssociationSetEnd;
						CsdlSemanticsAssociationSetEnd csdlSemanticsAssociationSetEnd2 = current.End2 as CsdlSemanticsAssociationSetEnd;
						if (current.End1.EntitySet == this && csdlSemanticsNavigationProperty.To == current.End2.Role)
						{
							this.Model.SetAssociationSetName(current.End1.EntitySet, property, current.Name);
							if (csdlSemanticsAssociationSetEnd != null && csdlSemanticsAssociationSetEnd2 != null)
							{
								this.Model.SetAssociationSetAnnotations(csdlSemanticsAssociationSetEnd.EntitySet, property, current.DirectValueAnnotations, csdlSemanticsAssociationSetEnd.DirectValueAnnotations, csdlSemanticsAssociationSetEnd2.DirectValueAnnotations);
							}
							IEdmEntitySet result = current.End2.EntitySet;
							return result;
						}
						if (current.End2.EntitySet == this && csdlSemanticsNavigationProperty.To == current.End1.Role)
						{
							this.Model.SetAssociationSetName(current.End2.EntitySet, property, current.Name);
							if (csdlSemanticsAssociationSetEnd != null && csdlSemanticsAssociationSetEnd2 != null)
							{
								this.Model.SetAssociationSetAnnotations(csdlSemanticsAssociationSetEnd2.EntitySet, property, current.DirectValueAnnotations, csdlSemanticsAssociationSetEnd2.DirectValueAnnotations, csdlSemanticsAssociationSetEnd.DirectValueAnnotations);
							}
							IEdmEntitySet result = current.End1.EntitySet;
							return result;
						}
					}
				}
			}
		}
	}
	return null;
}

As far as I understand this code is looking thru my entire model (which is huge) to find the link endpoint AND it does that for every link property for all entities returned by the service. I understand it has to do this as the Json format doesn't include it in the payload, but it surely shouldn't do it for every property of every entity in a feed.

Imagine a scenario wher I return 10,000 entities in a feed with an entity having 100 navigation properties - this will result in the above method being called 100x10000 = 1,000,000 times where each call will iterate the entire model trying to find the link endpoint.

The profiling were done on 5.6.0.0 Alpha. I know this is an Alpha release, but I have experienced the same hopeless performance on all prior releases as well.

Could you please have a look at this?

Regards

Uffe

   

Sidewinder X 6 update. skeleton.

$
0
0
Capturing skeleton joint data and writing the X,Y,Z values to a .csv
$.000650 Can you do a "Basic" update for the sidewinder X6 bios. eg Load"*",8,1 or eg a few common comands like Load"BooKs",8,1 and Run. and possibly a cut txt n print save?? cheer's Kind reguards Pete. PP. LTD

How to test for key present using WCF Data Service Reference classes?

$
0
0

When I issue a query like

Truck x = context.Trucks.FirstOrDefault(r => r.Id == "Tonka23");

My client-side query uses FirstOrDefault meaning give me the first match or give me a null, but don't throw an exception.

This use of FirstOrDefault fails at runtime with "Method not supported."  

Hmph.  Ok, I can turn it around into a Where clause to do the same thing (why doesn't it do this internally?):

Truck x = context.Trucks.Where(r => r.Id == "Tonka23").FirstOrDefault();

I can see that this gets converted into a request URI of "http://localhost/svc/Trucks('Tonka23')"

At runtime, this client side statement throws an exception because the server returns a 404 error.

On the server side, I have a self-hosted WCF service running WCF Data Services 5.5. I have implemented "GetOne(string id)" to look up the given id in an internal dictionary and return the object.  If the id doesn't exist, it throws a KeyNotFound exception, which I convert in HandleException into a DataServiceException with an HttpStatus code of 404.

If I change my server code to return null for an unknown id, an exception is still thrown by the WCF Data Services core for the null value and the service still returns 404. So the client code throws no matter what I do on the server. And given that the URI is requesting an entity by a key value that does not exist, I would think that 404 is the proper response from the server.

The only workaround I've found is to change the Where clause to disrupt the key field pattern matching to prevent WCFDS from using the index uri and persuade it to use a $filter expression instead:  

Truck x = context.Trucks.Where(r => r.Id == "Tonka23" || r.Id == "Tonka23").FirstOrDefault().

This produces a Request URI like "http://localhost/svc/Trucks?$filter=Id eq 'Tonka23' or Id eq 'Tonka23'

That query causes FirstOrDefault on the client to behave correctly - to return the target object if it exists, or return null if it does not exist, and not throw an exception.

How do I achieve the FirstOrDefault semantic using WCF Data Service Reference generated proxy classes without using this where clause hack? Is there a way to turn off the key field pattern matching?  Does the server need to return something special for WCF Data Services Client to behave correctly?


http://dannythorpe.com

Oracle db entry deletion problem when primary key contains a DateTime column.

$
0
0

Hi I am using WCF data services as an interface to an Oracle db. I have no problems querying, updating or adding entries through my client wcf data service consumer applicaton. However i cannot delete the entries of tables that contain a DateTime primary key. In contrast, i can delete entries when the primary key does not contain a DateTime primary key. Is this normal? Has this problem occured to anyone else?

 

Where is the sample source code said to accompany the "Data Service Provider Toolkit"?

$
0
0

On the following page:  http://msdn.microsoft.com/en-us/data/gg191846

There is clear reference made to source code in the following statement:

"If you’d like to start first by looking at some code before we discuss it, we’ll be working with the series of samples that accompany this document in the Data Service Provider Toolkit"

However, there is no clear link to a toolkit or to the source code being referred to.  This seems like a great teaching tool, but without the source code to which it refers, it is borderline useless!  Any suggestions?


How to do two level null propagation checks during projection using WCF DS Client?

$
0
0

Hi,

I cannot get this to work. I am trying to do a Query and project a realated entity and project one of the related entitys related entitiy. Sounds more complex than it is. Here is my code example:

var query =
    from file in context.Files
    select new File
    {
        ID = file.ID,
        CurrentReminder = file.CurrentReminder == null ? null : new Reminder
        {
            ID = file.CurrentReminder.ID,
            Name = file.CurrentReminder.Name == null ? null : new Name
            {
                ID = file.CurrentReminder.Name.ID
            }
        }
    };


The File type has a navigation property CurrentReminder of type Reminder, the property can be null for some File instances. The Reminder type has a Name property of type Name that can be null for some Reminder instances. So I need to have null propagation checks to not break desirialization on the client so I have the == null ? null : construct in the expression.

The generated OData request is correct and the server returns some File entities with null for Reminder and some with content.

I get an exception when WCF DS Client is deserializing the response. As far as I can tell the exception occurs on the client when deserializing a File entity that has a CurrentReminder and the CurrentReminder has a Name. The exception thrown states:

"An entity of type 'Services.OData.Name' cannot be projected because there is already an instance of type 'Services.OData.Reminder' for 'http://localhost/Services.OData.Web/OData.svc/Reminders('21')'."

It seems as if WCF DS Client got confused of what it is doing and mixing up the types. The full stack trace is:

System.InvalidOperationException: An entity of type 'Services.OData.Name' cannot be projected because there is already an instance of type 'Services.OData.Reminder' for 'http://localhost/Services.OData.Web/OData.svc/Reminders('21')'. at System.Data.Services.Client.Materialization.ODataEntityMaterializer.ProjectionInitializeEntity(ODataEntityMaterializer materializer, MaterializerEntry entry, Type expectedType, Type resultType, String[] properties, Func`4[] propertyValues) at System.Data.Services.Client.Materialization.ODataEntityMaterializerInvoker.ProjectionInitializeEntity(Object materializer, Object entry, Type expectedType, Type resultType, String[] properties, Func`4[] propertyValues) at _dynamic_ODataEntityMaterializerInvoker_ProjectionInitializeEntity(Object , Object , Type , Type , String[] , Func`4[] ) at lambda_method(Closure , Object , Object , Type ) at System.Data.Services.Client.Materialization.ODataEntityMaterializer.ProjectionInitializeEntity(ODataEntityMaterializer materializer, MaterializerEntry entry, Type expectedType, Type resultType, String[] properties, Func`4[] propertyValues) at System.Data.Services.Client.Materialization.ODataEntityMaterializerInvoker.ProjectionInitializeEntity(Object materializer, Object entry, Type expectedType, Type resultType, String[] properties, Func`4[] propertyValues) at _dynamic_ODataEntityMaterializerInvoker_ProjectionInitializeEntity(Object , Object , Type , Type , String[] , Func`4[] ) at lambda_method(Closure , Object , Object , Type ) at System.Data.Services.Client.Materialization.ODataEntityMaterializer.ProjectionInitializeEntity(ODataEntityMaterializer materializer, MaterializerEntry entry, Type expectedType, Type resultType, String[] properties, Func`4[] propertyValues) at System.Data.Services.Client.Materialization.ODataEntityMaterializerInvoker.ProjectionInitializeEntity(Object materializer, Object entry, Type expectedType, Type resultType, String[] properties, Func`4[] propertyValues) at _dynamic_ODataEntityMaterializerInvoker_ProjectionInitializeEntity(Object , Object , Type , Type , String[] , Func`4[] ) at lambda_method(Closure , Object , Object , Type ) at System.Data.Services.Client.ProjectionPlan.Run(ODataEntityMaterializer materializer, ODataEntry entry, Type expectedType) at System.Data.Services.Client.Materialization.ODataEntityMaterializer.ReadImplementation() at System.Data.Services.Client.MaterializeAtom.MoveNextInternal() at System.Data.Services.Client.MaterializeAtom.MoveNext() at System.Linq.Enumerable.<CastIterator>d__b1`1.MoveNext() 

Is this a bug in WCF DS Client or should I write the null propagation checks diferent?

Please note that it Works without null propagation checks for entities that has related entities (but fails for nulls as expected).

Please also note that if write the Query untyped it also Works. The equivalent untyped Query is:

var query =
    from file in context.Files.AddQueryOption("$expand", "CurrentReminder,CurrentReminder/Name").AddQueryOption("$select", "ID,CurrentReminder/ID,CurrentReminder/Name/ID")
    select file;

Please help - this is driving me nuts.

Regards Uffe


Exception: "A maximum number of 1000 operations are allowed in a change set"

$
0
0

We have upgraded our OData service to use WCF Data Services 5.0.1 (based on Nuget package). This broke some of applications with the following exception:

"ODataException: The current change set contains too many operations. A maximum number of 1000 operations are allowed in a change set"

After I downgraded WCF DS to the previous version (the one that comes with .NET 4.0) everything went back to normal.

Is 1000 the maximum that can't be exceeded? I tried the following settings:

config.MaxChangesetCount = 65535;
config.MaxBatchCount = 65535;

but didn't help.

This seems to be a breaking change, and it is quite unfortunate that it is not documented. And by the way what is the default values for WCF DS 4.0?

Vagif


Vagif Abilov


Mishandling with guid

$
0
0

I need to increase some sizes and I do that:

<webHttpBinding>
     <binding name="WdsBinding" maxReceivedMessageSize="10000000">
            <readerQuotas maxArrayLength="1024000" />
             <security mode="Transport">
                       <transport clientCredentialType="Windows" />
              </security>
   </binding>
  </webHttpBinding>


   <service name="My.Web.Services.WcfDataService">
            <endpoint address="" binding="webHttpBinding" contract="System.Data.Services.IRequestHandler"

                   bindingConfiguration="WdsBinding" />
  </service>

After that some procedures won't be executed:

Example:

[WebGet]

public void Method(Guid guid)

{....}

400 Bad Request

What I missed in configuration?

using WCF and EF Associated query multiple tables

$
0
0

 

i am sorry for my pool english  ; 

I'm working on a project using WCF data services with the Entity Framework provider, 

when i query association table and return the ef entity .

the wcf will be throw the exception : the remote host connection was forcibly closed ,

i guess the exception is caused by Proxy , i have set the Configuration.ProxyCreationEnabled = false , 

but does not work , so , i need some help  to resolve the problem . 

thanks for everybody advices

413 Error in WCF Data Services - Request Entity Too Large

$
0
0

I am getting this error when I am trying to send a string of length 68000 characters to the service to insert into the DB.

But on the context.savechanges() line, it is giving this error.

As per the googled articles, I have increased the maxReceivedFilesize parameter & below is the service web.config:

<?xml version="1.0"?>

<configuration>

  <connectionStrings>

    <add name="CRFR_DB_Entities" connectionString="metadata=res://*/ModelCRFREntities.csdl|res://*/ModelCRFREntities.ssdl|res://*/ModelCRFREntities.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=CANATHOSTDEVDB2\SQL3;initial catalog=CRFR_DB_DEV;integrated

security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />

  </connectionStrings>

  <appSettings>

    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />

  </appSettings>

  <system.web>

    <compilation debug="true" targetFramework="4.5" />

    <httpRuntime targetFramework="4.5" maxRequestLength="2147483647" executionTimeout="360000"/>

  </system.web>

  <system.serviceModel>

<services>

      <service name="Deloitte.CA.CRFR.DataRepositoryService.CRFRDataService" >

  <endpoint binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IEmailService" contract="System.Data.Services.IRequestHandler" address="REST"></endpoint>

      </service>

    </services>

    <bindings>

      <basicHttpBinding>

      <binding name="BasicHttpBinding_IEmailService" messageEncoding="Mtom" transferMode="Streamed" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">

<readerQuotas maxDepth="128" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />

        </binding>

      </basicHttpBinding>

    </bindings>

    <behaviors>

      <serviceBehaviors>

        <behavior>

          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->

          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>

          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing

exception information -->

          <serviceDebug includeExceptionDetailInFaults="false"/>

        </behavior>

      </serviceBehaviors>

    </behaviors>

    <protocolMapping>

        <add binding="basicHttpsBinding" scheme="https" />

    </protocolMapping>   

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

  </system.serviceModel>

  <system.webServer>

    <modules runAllManagedModulesForAllRequests="true"/>

    <!--

        To browse web app root directory during debugging, set the value below to true.

        Set to false before deployment to avoid disclosing web app folder information.

      -->

    <directoryBrowse enabled="true"/>

  </system.webServer>

</configuration>

Please let me know if I am missing anything, as I am still getting this error.

Bug: WCF DS Client fails to update OperationDescriptors (Actions) even in MergeOption.OverwriteChanges mode.

$
0
0

Hi,

Actions can be state dependent.

When doing updates (or caling Actions - that by definition has side effects) WCF DS Client correctly updates the properties on the client entity with the server values when using MergeOption.OverwriteChanges. However it fails to do so for the OperationDescriptors (the Actions) in the EntityDescriptor for the entity.

This must be a bug.

Actually it should ALWAYS overwrite the OperationDescriptors regardless of the MergeOption as the availability of an Action is always decided by the server.

An example scenario is as follows...

1. Say i have a Movie type with two state dependent Actions, CheckOut and CheckIn.

2. If the Movie is in a checked in state the CheckOut action is advertized but not the CheckIn action and vice versa.

3. Now query for some Movie in the checked in state and look at the available Actions on the movie by calling context.GetEntityDescriptor(movie).OperationDescriptors. Notice that the CheckOut Action is in the collection and the CheckIn action is not. This is as expected.

4. Now call the CheckOut action like this context.Execute(context.GetEntityDescriptor(movie).OperationDescriptors.Where(a => a.Title = "CheckOut").Single().Target, "POST").

5. The Movie is now in the checked out state on the server.

6. Refetch it on the client and inspect the result return from the server (using Fiddler) and verify that the CheckOut action is no longer advertized, but the CheckIn action is.

7. Now look at the context.GetEntityDescriptor(movie).OperationDescriptors for the movie. It still shows the CheckOut action as being present and not the CheckIn action. This is not as expected.

8. This wrong behaviour is independent of the MergeOption setting on the context.

Btw I am running on WCF DS 5.4.0.0

Kind regards

Uffe


Submit bugs for WCFDS 5.5?

WCFDS returning botched error data with HTTP 200 Ok

$
0
0

WCF Data Services 5.5 OData running in a self-hosted WCF service (no IIS). There is no EDM model; the service is running on POCO data types.

Submitting this request:

GET http://localhost/mysvc/$metadata HTTP/1.1

Accept: application/json, text/javascript, */*; q=0.01

We get back the following response:

HTTP/1.1 200 OK

Cache-Control: no-cache

Content-Length: 125

Content-Type: application/xml;charset=utf-8

Server: Microsoft-HTTPAPI/2.0

X-Content-Type-Options: nosniff

DataServiceVersion: 3.0;

Date: Fri, 05 Jul 2013 19:27:46 GMT

 

{"odata.error":{"code":"500","message":{"lang":"en-US","value":"An error occurred while trying to write an error payload."}}}

There are so many things wrong here.  The body is JSON formatted (as requested), but the content-type in the response is application/xml.  The body indicates there was an error, but the HTTP status code is 200 OK.  And the error text in the body isn't the text of the actual exception that occurred.

In stepping through our server code, I can see that an exception is thrown somewhere in the underbelly of WCFDS and the exception passes through our overridden DataService.HandleException method. The exception is ODataException: "No model was specified in the ODataMessageWriterSettings..."  We don't implement any ODataMessageWriters, we use WCFDS default stuff across the board.

We bundle this up in a DataServiceException wrapper, set the status code to 400 Bad Request, and return it to the caller.

I know that WCFDS 5.5 and earlier do not support returning the $metadata document in any format other than XML. However, the Accept header on the request includes a lowest priority */* media type option which should allow the server to choose to respond with XML. With the combination of multiple media type options in the Accept header, something in core WCF Data Services is getting confused.

Any ideas?

Thanks,

-Danny


http://dannythorpe.com

WCF DataService throws ConnectionString initialization exception on insert

$
0
0

My WCF Data Service works great when I fetch data from it. When I try to insert new data, I get the following exception:

The ConnectionString property has not been initialized

The only thing I modified is to use my partial class that tells to use the connection string name:

 MyExtEntities(string connectionString) : base(connectionString) 
{ ... }

And I overrode the CreateDataSource, so always have the proper context:

protected override MyExtEntities CreateDataSource()
{
    MyExtEntities entities = null;
    try
    {
        entities = new MyExtEntities ("name=MyExtEntities");
        ...
        return entities;

And you can believe, the config file contains that key:

add name="MyExtEntities " connectionString="metadata=res://*...

The stack shows that the core system is running, nothing from my methods:

System.Data.EntityClient.EntityConnection.Open() 
 at: System.Data.Objects.ObjectContext.EnsureConnection() 
 at: System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)

at: System.Data.Entity.Internal.InternalContext.SaveChanges() 
at: System.Data.Entity.Internal.LazyInternalContext.SaveChanges() 
at: System.Data.Entity.DbContext.SaveChanges() 
at: lambda_method(Closure , Object ) 
at: System.Data.Services.Providers.DbContextHelper.<>c_DisplayClass4.b_0() 
at: System.Data.Services.Providers.ObjectContextServiceProvider.SaveContextChanges() 
at: System.Data.Services.Providers.ObjectContextServiceProvider.SaveChanges() 
at: System.Data.Services.Providers.EntityFrameworkDataServiceProvider.SaveChanges() 
at: System.Data.Services.DataService1.HandleNonBatchRequest(RequestDescription description 
at: System.Data.Services.DataService1.HandleRequest()

I already added this to OnStartProcessingRequest:

protected override void OnStartProcessingRequest(ProcessRequestArgs args)
{
    if (this.CurrentDataSource == null)
        this.CreateDataSource();
    base.OnStartProcessingRequest(args);
}
I debugged the partial class of my Context, and whenever the CreateDataSource was hit, ConnectionString was never null or empty. What context is used on insert if the only one I overrode is always initialized?
It's really strange that the fetching works and it uses the same connection... What should I check?





Andris


Annotations on non-bindable actions

$
0
0

We have a problem with creating annotations for non-bindable actions. I am not sure if I have misunderstood, doing things wrong or if this is a bug.

We have a implementation of wcf data services where we want support for enums both on server and on the generated client both to include documentation around the actual enums and because it looks a lot better using enums in code.

In our solution we basically expose enums as their enumerated type in the metadata and add annotations of the actual enum type which then is inspected by our client generation code which creates a client with the correct enum types. However there seems to be a problem annotating non-bindable actions.

This is how the annotations look for the bindable actions:

<Annotations Target="Namespace.ContainerName/SetStatus">

<ValueAnnotation Term="Namespace.EnumDataType" Qualifier="statusParameter" String="Namespace.StatusEnum"/>

</Annotations>

The problem here is that annotations for targets which does not exists does not show in the service metadata. The above example works fine but when trying to target a non-bindable action I simply can not figure out what the target should be.

I have tried targetting the non-bindable action the following ways:

- ActionName

- Namespace.ActionName

- ClientNamespace.ActionName

- DefaultContainer.ActionName

- Namespace.DefaultContainer.ActionName

None of the above works and the only way I currently know to get the annotations show in the metadata is to target the non-bindable actions to a existing container which is not an acceptable solution.

So my questions is:

1) How do I target non-bindable actions in annotations?

2) Is this a bug? And in this case which one of the proposed targets is the correct one?

Performance/throughput issue in WCF DS Client System.Data.Services.Client.QueryResult.ExecuteQuery

$
0
0

Hi,

Consider the following scenario. From client code written with WCF DS Client you are querying an OData server that returns a (large) feed in streamed mode. The first entry in the feed arrives at the client almost immediatly and the last entry arrives after lets say 5 seconds. With client code resembling the following i would expect the first Console.Write almost instantaneously, but it does not - it actually waits untill all data has been retrieved from the server (the 5 seconds).

var q = from f in context.Files
    select f;

foreach (var f in q)
    Console.Write('.');

Digging a bit into the problem I found that this delay is due to WCF DS Client doing a stream copy of the response stream from the server as part of execute (before enumerating starts or triggered by starting enumerating).

IlSpy revealse the following implementation of QueryResult.ExecuteQuery (that is called from DataServiceRequest.Execute).

internal void ExecuteQuery()
{
	try
	{
		if (this.requestContentStream != null && this.requestContentStream.Stream != null)
		{
			this.Request.SetRequestStream(this.requestContentStream);
		}
		IODataResponseMessage syncronousResponse = this.RequestInfo.GetSyncronousResponse(this.Request, true);
		this.SetHttpWebResponse(Util.NullCheck<IODataResponseMessage>(syncronousResponse, InternalError.InvalidGetResponse));
		if (HttpStatusCode.NoContent != this.StatusCode)
		{
			using (Stream stream = this.responseMessage.GetStream())
			{
				if (stream != null)
				{
					Stream asyncResponseStreamCopy = this.GetAsyncResponseStreamCopy();
					this.outputResponseStream = asyncResponseStreamCopy;
					byte[] asyncResponseStreamCopyBuffer = this.GetAsyncResponseStreamCopyBuffer();
					long num = WebUtil.CopyStream(stream, asyncResponseStreamCopy, ref asyncResponseStreamCopyBuffer);
					if (this.responseStreamOwner)
					{
						if (0L == num)
						{
							this.outputResponseStream = null;
						}
						else
						{
							if (asyncResponseStreamCopy.Position < asyncResponseStreamCopy.Length)
							{
								((MemoryStream)asyncResponseStreamCopy).SetLength(asyncResponseStreamCopy.Position);
							}
						}
					}
					this.PutAsyncResponseStreamCopyBuffer(asyncResponseStreamCopyBuffer);
				}
			}
		}
	}
	catch (Exception e)
	{
		base.HandleFailure(e);
		throw;
	}
	finally
	{
		base.SetCompleted();
		this.CompletedRequest();
	}
	if (base.Failure != null)
	{
		throw base.Failure;
	}
}

Is there a good reason for the implementation doing so? Or is it a bug? Please explain.

As I see it there are several problems with doing this.

1. As described it will take longer to get all data processed on the client.

2. In scenarios where the client don't want any change tracking but just want the data and do some calculations or handing it off to some other party you get an unnecessary memory consumption hit by keeping the full response in memory.

I do know I could write the same code using ODataLib and an ODataReader and get a proper streaming model without this overhead, but it is a lot more complex four our partners to go the ODataLib route.

Regards

Uffe

store app and portable WCF Data Services (5.6.0.0)

$
0
0

I have a Store Class Library and a Store App in the same solution.

I added the latest WCF Data Services Client to both:

Install-Package Microsoft.Data.Services.Client -Pre

The Classlibrary build fine, howoever the store app produces an error when build:

Error 2 MSB3815: Satellite assembly "C:\Users\Ben\Documents\Visual Studio 2012\Projects\Spotted\packages\Microsoft.Data.Edm.5.6.0-alpha1\lib\portable-net40+sl5+wp8+win8\zh-Hans\Microsoft.Data.Edm.Portable.resources.dll" was built improperly. The manifest resource "Microsoft.Data.Edm.zh-HANS.resources" will not be found by the ResourceManager.  It must end in ".zh-Hans.resources". MyProject

and 5 more of these (same kind of error).

Looking in refelection, the resoures are indeed ending in uppercase HANS.

I cannot get it too work, lost many hours just trying to resolve these issues.

Any help appreciated,

Thanks,

  Ben

Exists clauses in Odata generated Queries may contain unneeded columns

$
0
0

Hello,

during the use of odata for Informix I found that the query
generating for tables which have many columns and contexts for more tables  could
be more performant.

My context is like :

Expand("artikel,artikel/pranw_ziel/verbotenezelle,aktivemischan
,plinie,artikel/art_press/pressanw")

What I found is that the genration pattern for the queries makes use
of Exists clauses which are all generated like :

select col1,col2,col3

from xy

where EXISTS (SELECT     CAST(1 AS int) AS C1    FROM 
    (SELECT
Extent17.art_nr AS art_nr, Extent17.zelle AS zelle, Join16.a_nr,
   
Join16.a_name, Join16.a_such, Join16.a_dichte, Join16.a_pgr_nr,
   
Join16.a_stueck_kg, Join16.a_vpe, Join16.a_pe_nr, Join16.a_preis,
   
Join16.a_dekl_nr, Join16.a_agnr, Join16.a_gruppe, Join16.a_bestzul,
   
Join16.a_haltbarkeit, Join16.a_melde, Join16.a_abteilungs_nr,
   
Join16.a_ref_nr, Join16.a_pr_nr, Join16.a_zusatz_anr,
   
Join16.a_zusatz_proz, Join16.a_sack_anr, Join16.a_bemerkung,
   
Join16.a_ab_nr, Join16.a_inh_menge, Join16.a_inh_krit,
Join16.a_pr_anzahl,
    Join16.a_aktiv, Join16.a_dispo_nr,
Join16.a_dispo_wahl, Join16.a_bediener,
    Join16.a_datum, Join16.a_iris_nr,
Join16.a_ean, Join16.a_keko_best_nr,
    Join16.ifx_insert_checksum,
Join16.ifx_row_version, Join16.ap_artikel_nr,
    Join16.ap_pa_nr,
Join16.ap_misch_fett, Join16.ap_mehl_dichte,
    Join16.ap_pelletlaenge,
Extent20.z_intern AS z_intern, Extent20.z_extern
    AS z_extern,
Extent20.z_p_linie AS z_p_linie, Extent20.z_art AS z_art, ....

As you see ( this is a fragment of an original query from a bigger
context ...

What happens is that these queries cause heavy use of the tempdb
because they also join Multi column subselects whith each other.  The first most
inexpensve way to optimize these gind of generated queries seems to be to
eliminate the generation of innecessary columns in the inner part of the exists
brackets . Except from the columns which are needed for join or filter purposes
the other columns of the tables are not needed within the exists part. Here they
cause load on the tempdb because during the process there are tables generated
in the tempdb which contain all of the columns of the select list.

 I have one query optimized manually from 1 Minute 11sec  down to  17
seconds by eliminationg the unneeded columns in the exists part of the
 generated query.

So my question is  which part of odata is responsible for generating the columns in the exists part of the query ?

Is it the Driver  or the odata - module ?

Would it be possible to reduce the number of columns in the exists part of the generated queries ?

Thank you very much .

 

 

WCF Data Service | One-to-many relationships issue

$
0
0

Hi,

I'm building a very simple WCF Data Service (odata), to be consumed by a LightSwitch app..

I'm not using ADO.NET or any Database related contexts / tools.. just POCO

Let's say we have 2 entities: Parent, and Child.. They have a 1-n relationship (parent can have many children, a child must have one parent). 

I set up the classes as below:

 [DataServiceKeyAttribute("ID")]
 public class Parent
 {
   public int ID { get; set; }
   public string ParentName { get; set; }
   public List<Child> Children { get; set; }
 }

 [DataServiceKeyAttribute("ID")]
 public class Child
 {
   public int ID { get; set; }
   public string ChildName { get; set; }
   public Parent Parent { get; set; }
 }

And I created a simple context class:

 public class FamilyContext
    {
        private List<Parent> generateSomeParents()
        { ... }

        private List<Child> generateSomeChildren()
        { ...  }
        public IQueryable<Parent> Parents
        {
            get { 
                return generateSomeParents().AsQueryable(); 
            }
        }

        public IQueryable<Child> Children
        {
            get { 
                return generateSomeChildren().AsQueryable()
            }
        }
    }

And for the data service:

public class FamilyWcfDataService : DataService<FamilyContext>
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
            // Examples:
             config.SetEntitySetAccessRule("Parents", EntitySetRights.AllRead);
             config.SetEntitySetAccessRule("Children", EntitySetRights.AllRead);
            // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
        }
    }

The problem is: When I run the service, and view the $metadata, I get 2 associations! see this:

<edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" Version="1.0"><edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="1.0" m:MaxDataServiceVersion="3.0"><Schema xmlns="http://schemas.microsoft.com/ado/2006/04/edm" Namespace="ODataServer.Models"><EntityType Name="Parent"><Key><PropertyRef Name="ID"/></Key><Property Name="ID" Type="Edm.Int32" Nullable="false"/><Property Name="ParentName" Type="Edm.String"/><NavigationProperty Name="Children" Relationship="ODataServer.Models.Parent_Children" ToRole="Children" FromRole="Parent"/></EntityType><EntityType Name="Child"><Key><PropertyRef Name="ID"/></Key><Property Name="ID" Type="Edm.Int32" Nullable="false"/><Property Name="ChildName" Type="Edm.String"/><NavigationProperty Name="Parent" Relationship="ODataServer.Models.Child_Parent" ToRole="Parent" FromRole="Child"/></EntityType><Association Name="Parent_Children"><End Type="ODataServer.Models.Parent" Role="Parent" Multiplicity="*"/><End Type="ODataServer.Models.Child" Role="Children" Multiplicity="*"/></Association><Association Name="Child_Parent"><End Type="ODataServer.Models.Parent" Role="Parent" Multiplicity="0..1"/><End Type="ODataServer.Models.Child" Role="Child" Multiplicity="*"/></Association><EntityContainer Name="FamilyContext" m:IsDefaultEntityContainer="true"><EntitySet Name="Parents" EntityType="ODataServer.Models.Parent"/><EntitySet Name="Children" EntityType="ODataServer.Models.Child"/><AssociationSet Name="Parent_Children" Association="ODataServer.Models.Parent_Children"><End Role="Parent" EntitySet="Parents"/><End Role="Children" EntitySet="Children"/></AssociationSet><AssociationSet Name="Child_Parent" Association="ODataServer.Models.Child_Parent"><End Role="Child" EntitySet="Children"/><End Role="Parent" EntitySet="Parents"/></AssociationSet></EntityContainer></Schema></edmx:DataServices></edmx:Edmx>

How can I make sure I get 1 association only, with (1-n) relationship? 

[Note: by I was able to get (0..1-n) relationship by deleting the 'List<Child> Children' propery.. but it didn't seem right.. It affects navigation properties feature]

Your help is extremely appreciated..

Thanks

Viewing all 877 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>