Pergunta

I'm developing a VS2010 solution based on this framework: http://ntieref.codeplex.com/.
Everything is ok, and I can query my database (MS SQLServer 2008) and save changes.

Now I'm trying to query a table (Projects) joining it with another one (project-user association) and filtering by key (user key) like this:

var query = from p in ctx.C__E_PROJECTS.AsQueryable()
            join pu in ctx.CUMR_USER_PROJECTS_ASSOCIATION.AsQueryable() on p.CD_PROJECT equals pu.RF_PROJECT
            where pu.RF_USER == 1
            select p;

but I get a [System.NotImplementedException] = {"The method or operation is not implemented."} at NTier.Client.Domain\QueryProvider.cs:line 382 (which is part of N-Tier Entity Framework library).

Also replacing the join like this gives the same exception:

var query2 = from p in ctx.C__E_PROJECTS.AsQueryable()
             from pu in ctx.CUMR_USER_PROJECTS_ASSOCIATION.AsQueryable()
             where p.CD_PROJECT == pu.RF_PROJECT
                && pu.RF_USER == 1
             select p;

Am I doing something wrong?
Is there another way to get a table filtered in join with another table?

This is the definition of the two tables: (where Entity is NTier.Common.Domain.Model.Entity)

[DataContract(IsReference = true)]
[KnownType(typeof(C__E_PROJECT_VERSIONS))]
[KnownType(typeof(CUMR_USER_PROJECTS_ASSOCIATION))]
[MetadataType(typeof(C__E_PROJECTSMetadata))]
public class C__E_PROJECTS : Entity<C__E_PROJECTS>, INotifyPropertyChanged, INotifyPropertyChanging, IDataErrorInfo
{
    public C__E_PROJECTS();

    [DataMember]
    [NavigationProperty]
    public TrackableCollection<C__E_PROJECT_VERSIONS> C__E_PROJECT_VERSIONS { get; set; }
    [DataMember]
    [Required]
    [SimpleProperty]
    [ServerGeneration(1)]
    [Key]
    public int CD_PROJECT { get; set; }
    [NavigationProperty]
    [DataMember]
    public TrackableCollection<CUMR_USER_PROJECTS_ASSOCIATION> CUMR_USER_PROJECTS_ASSOCIATION { get; set; }
    [DataMember]
    [SimpleProperty]
    public string DS_PROJECT { get; set; }
    [SimpleProperty]
    [DataMember]
    [Required]
    public string ID_PROJECT { get; set; }

    protected override void ClearNavigationProperties();
    protected override int GetKeyHashCode();
    protected override bool IsKeyEqual(C__E_PROJECTS entity);
}

[DataContract(IsReference = true)]
    [KnownType(typeof(CUME_USERS))]
    [MetadataType(typeof(CUMR_USER_PROJECTS_ASSOCIATIONMetadata))]
    [KnownType(typeof(C__E_PROJECTS))]
    public class CUMR_USER_PROJECTS_ASSOCIATION : Entity<CUMR_USER_PROJECTS_ASSOCIATION>, INotifyPropertyChanged, INotifyPropertyChanging, IDataErrorInfo
    {
        public CUMR_USER_PROJECTS_ASSOCIATION();

        [NavigationProperty]
        [DataMember]
        public C__E_PROJECTS C__E_PROJECTS { get; set; }
        [DataMember]
        [SimpleProperty]
        public bool? CAN_READ { get; set; }
        [DataMember]
        [NavigationProperty]
        public CUME_USERS CUME_USERS { get; set; }
        [DataMember]
        [Key]
        [Required]
        [SimpleProperty]
        public int RF_PROJECT { get; set; }
        [SimpleProperty]
        [Key]
        [DataMember]
        [Required]
        public int RF_USER { get; set; }

        protected override void ClearNavigationProperties();
        protected override int GetKeyHashCode();
        protected override bool IsKeyEqual(CUMR_USER_PROJECTS_ASSOCIATION entity);
    }


As a workaround I've implemented the join query in a SQL Server stored procedure which returns the query result and I added the stored procedure to the edmx model. Everything ok.
Now saving the edmx or running the "N-Tier Entity Generator" custom tool I expected to have the related function in the context at client side, but it is missing. I can see it in the XXX.Server.Domain.Repositories project, but it is not propagated to the client. Do I have to edit the T4 templates?

Thank you!
Roberto

Foi útil?

Solução 2

In general ...

N-Tier Entity Framework generates client and server code to query entities supporting sorting (orderby etc.), filtering (where), paging (skip and take), and including relations (include). This operations are end-to-end i.e. client define linq queries, transmitted to server via WCF and eventually executed on the database. More sophisticated query operations like projections, aggregations, and joins can be added manually either on server (DataService) or client data context (DataContext). All relevant interfaces and classes are generated as partial and my easily be extended using partial interfaces and classes:

on server

-   partial interface IMyDataService
-   partial class MyDataService

and on client

-   partial interface IMyDataContext
-   partial class MyDataContext

Also, stored procedures are not automatically exposed by the framework generated code. If you would like so, either modify code generation (T4 files) or add custom methods to data service and client data context.

In your case ...

Depending on what your intension is you could do something like:

var query = 
  from p in ctx.PROJECTS.AsQueryable()
                        .Include(“USER_PROJECTS_NAVIGATION_PROPERTY”)
  where p.USER_PROJECTS_NAVIGATION_PROPERTY.RF_USER == 1
  select p;

Or if you need something more complex, implement it as a custom method using the partial classes listed above.

Outras dicas

Regarding your update ,try this:

var query = from p in ctx.PROJECTS.AsQueryable().Include("USER_PROJECTS_ASSOCIATION")
            from q in p.USER_PROJECTS_ASSOCIATION.AsQueryable()
            where q.USER_PROJECTS_ASSOCIATION.RF_USER==1
            select p; // or try Select q;

I hope it will help you.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top