WCF Contracts from Entity Framework?




I've been coming up with a lot of dead ends on this question. Supposedly, .NET 3.5 SP1 has Support for ADO.NET Entity Framework entities in WCF contracts. But when I look for solid info on it I'm not getting a lot of answers. I found this one snippet on an MSDN thread. Does anyone have any experience with this? What happened to the [DataContract]? Is this all there is to it? Why is there so little material on this?


This the answer from Tim Mallalieu in Microsoft.


Entity Types that are generated in the Entity Framework are, by default Data Contracts.
If I were to create a simple model in the Entity Designer like the following:
The cart Entity Type is by default a DataContract with all properties annotated as data members. We can then use this in a WCF service as follows:



```
[ServiceContract]

public interface IService1

{
    [OperationContract]
    Cart[] AllCarts();
}



public class Service1 : IService1

{
    public Cart[] AllCarts() 

    {
        using (MSPetShop4Entities context = new MSPetShop4Entities())

        {
            var carts = from c in context.Carts select c;
            return carts.ToArray();
        }
    }
}

```

As the Entities are DataContracts you can now roll your services as you see fit and send these across the wire.
You could go the easy way and use [ADO.NET Data Services](http://codebetter.com/blogs/david.hayden/archive/2008/01/08/getting-started-with-ado-net-data-services.aspx).
I have now implemented the following solution.


As CodeNotFound pointed out in the comments, IdentityUser used to have a `Roles` property. This is no longer the case in .NET Core. This [comment/issue](https://github.com/aspnet/Identity/issues/1361#issuecomment-348863959) on GitHub seems to be the current solution for .Net Core. I have attempted to implemented it with the following code:


**ApplicationUser**



```
public class ApplicationUser : IdentityUser
{
    public ICollection<ApplicationUserRole> UserRoles { get; set; }
}

```

**ApplicationUserRole**



```
public class ApplicationUserRole : IdentityUserRole<string>
{
    public virtual ApplicationUser User { get; set; }
    public virtual ApplicationRole Role { get; set; }
}

```

**ApplicationRole**



```
public class ApplicationRole : IdentityRole
{
    public ICollection<ApplicationUserRole> UserRoles { get; set; }
}

```

**DBContext**



```
public class ApplicationDbContext
    : IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserClaim<string>,
    ApplicationUserRole, IdentityUserLogin<string>,
    IdentityRoleClaim<string>, IdentityUserToken<string>>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<ApplicationUserRole>(userRole =>
        {
            userRole.HasKey(ur => new { ur.UserId, ur.RoleId });

            userRole.HasOne(ur => ur.Role)
                .WithMany(r => r.UserRoles)
                .HasForeignKey(ur => ur.RoleId)
                .IsRequired();

            userRole.HasOne(ur => ur.User)
                .WithMany(r => r.UserRoles)
                .HasForeignKey(ur => ur.UserId)
                .IsRequired();
        });
    }
}

```

**Startup**



```
services.AddIdentity<ApplicationUser, ApplicationRole>(options => options.Stores.MaxLengthForKeys = 128)
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

```

Finally, make sure when you're using it that you eagerly load the User's UserRoles, and then the UserRole's Role like so:



```
this.Users = userManager.Users.Include(u => u.UserRoles).ThenInclude(ur => ur.Role).ToList();

```

I had an issue where the `Role` property of each `UserRole` was null and this was resolved by adding in the `.ThenInclude(ur => ur.Role)` part.


Microsoft doc on multi-level eager loading: <https://docs.microsoft.com/en-us/ef/core/querying/related-data#including-multiple-levels> The basic idea here is that your adding properties to the model that EF can use to make a relationship. Right you're trying to create a relationship of type `User` and that is creating an error. To assign a composite key each key needs to be a type compatible with a `Key` field, not a navigation property. So we add `UserId` and `FriendId` of type `int`, `string` or `GUID` etc. and create a relationship off those properties.



```
public class Relationship
{
    public User Friend { get; set; }

    public User User { get; set; }

    public int FriendId { get; set; }

    public int UserId { get; set; }

    public DateTimeOffset RelationshipInitializationDate { get; set; }
}

public class User
{
    public int UserId { get; set; }
}

```

You can now define a composite key across `UserId` and `FriendId`. Something like this should do:



```
public class NorthwindContext : DbContext
{
     public NorthwindContext(DbContextOptions<NorthwindContext> options):base(options) { }

     public NorthwindContext() { }

     protected override void OnModelCreating(ModelBuilder builder)
     {
         builder.Entity<Relationship>().HasKey(table => new {
         table.FriendId, table.UserId
         });
     }
     public DbSet<Relationship> Relationships { get; set; }
     public DbSet<User> Users { get; set; }
}

```

[Source: Medium - How To: Entity Framework Core relationships, composite keys, foreign keys, data annotations, Code First and Fluent API](https://medium.com/radzenhq/how-to-entity-framework-core-relationships-composite-keys-foreign-keys-data-annotations-code-f4b238086463) As I understand, you are following the following approach:



```
modelBuilder.Entity<IdentityRole>().HasData(new IdentityRole { Name = "Admin", NormalizedName = "Admin".ToUpper() });

```

There are two problems with this code.


The first is the usage of `modelBuilder.Entity<IdentityRole>()`. This makes `IdentityRole` class to be treated by EF Core as an *entity*, hence the `IdentityRoles` table it tries to create. It's because `IdentityRole` class is *different* from what your model is using - `IdentityRole<Guid>`. Change it to `modelBuilder.Entity<IdentityRole<Guid>>()` (and also the `new` operator) and the problem will be solved.


The second problem is that `HasData` *requires* PK values to be specified, as explained in the [Data Seeding](https://docs.microsoft.com/en-us/ef/core/modeling/data-seeding) section of the EF Core documentation:



> 
> The primary key value needs to be specified even if it's usually generated by the database. It will be used to detect data changes between migrations.
> 
> 
> 


So additionally to changing the `HasData` generic type argument, you need to pre generate Guid to be used as Id for the new role (see [Entity Framework Core Auto Generated guid](https://stackoverflow.com/questions/53493025/entity-framework-core-auto-generated-guid/53495148#53495148) for more details a the similar issue) and use something like this:



```
modelBuilder.Entity<IdentityRole<Guid>>().HasData(
    new IdentityRole<Guid>
    {
        Id = new Guid("pre generated value"),
        Name = "Admin",
        NormalizedName = "Admin".ToUpper()
    }
);

``` Entity Framework Core does not have lazy loading implemented at this time (RTM Build).


It is recommended that you do eager loading by using an .Include extension method. It is also a good idea to use a repository to do the eager loading for you.


Reference: <https://github.com/aspnet/EntityFramework/issues/3797> Dapper just wraps raw ADO.NET; raw ADO.NET doesn't offer a facility for this, therefore dapper does not. What you want is `SqlBulkCopy`. You could *also* use a table-valued-parameter, but this really feels like a `SqlBulkCopy` job.


In a pinch, you can *use* dapper here - `Execute` will unroll an `IEnumerable<T>` into a series of commands about `T` - but it will be lots of commands; and unless you explicitly enable async-pipelining, it will suffer from latency per-command (the pipelined mode avoids this, but it will still be n commands). But `SqlBulkCopy` will be *much* more efficient.


If the input data is an `IEnumerable<T>`, you might want to use `ObjectReader` from FastMember; for example:



```
IEnumerable<SomeType> data = ...
using(var bcp = new SqlBulkCopy(connection))
using(var reader = ObjectReader.Create(data, "Id", "Name", "Description"))
{
    bcp.DestinationTableName = "SomeTable";
    bcp.WriteToServer(reader);
}

``` hi [@m3nt0r](/u/m3nt0r),

i would look at existing marketplaces which likely have a wide audience to see if this was suitable for your use case e.g. opensea, rather than creating your own sale contract.

[image] m3nt0r:

how do you implement in solidity the ability to give ownership of the nft to the buyer in… need to add 



```
services.AddEntityFrameworkSqlite().AddDbContext<ApplicationDbContext>();

```

and delete



```
services.AddIdentity<IdentityUser, IdentityRole>()
                    .AddEntityFrameworkStores<ProductContext>();

```

in startup.
the error was about bad startup configuration.
Was sending too much things.


ApplicationDbContext:



```
 public class ApplicationDbContext : IdentityDbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }
        public Microsoft.EntityFrameworkCore.DbSet<Product> Products { get; set; }
        public Microsoft.EntityFrameworkCore.DbSet<List> Lists { get; set; }

        public Microsoft.EntityFrameworkCore.DbSet<ProductList> ProductLists { get; set; }


        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);

             optionsBuilder.UseSqlite("Data Source=assistant.db");

        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<ProductList>()
                .HasKey(pl => new { pl.ProductId, pl.ListId });

            modelBuilder.Entity<ProductList>()
                .HasOne(pl => pl.Product)
                .WithMany(p => p.ProductList)
                .HasForeignKey(pl => pl.ProductId)
                .OnDelete(DeleteBehavior.Cascade);

            modelBuilder.Entity<ProductList>()
                .HasOne(pl => pl.List)
                .WithMany(l => l.ProductList)
                .HasForeignKey(pl => pl.ListId)
                .OnDelete(DeleteBehavior.Cascade);
        }
    }

``` I've had great success with [wsdl2php](https://github.com/jbarciauskas/wsdl2php). It will automatically create wrapper classes for all objects and methods used in your web service. you can use dedicated package for azure:

[image]

and grab key with this activity:

[image]

there’s no direct way to push key to dataservice. this must be done by taking it from azure and push to dataservice using dedicated packages. more information about dataservice and entities are here:

… You are mixing [expressions](https://docs.microsoft.com/en-us/dotnet/api/system.linq.expressions.expression?view=netframework-4.7.1) with [lambda expressions](https://docs.microsoft.com/en-us/dotnet/api/system.linq.expressions.lambdaexpression?view=netframework-4.7.1). There are many posts showing how you can combine lambda expressions, but the essential part is to compose expressions from lambda expression [bodies](https://docs.microsoft.com/en-us/dotnet/api/system.linq.expressions.lambdaexpression.body?view=netframework-4.7.1) and rebind the [parameters](https://docs.microsoft.com/en-us/dotnet/api/system.linq.expressions.lambdaexpression.parameters?view=netframework-4.7.1).


The later is usually achieved by a custom [`ExpressionVisitor`](https://docs.microsoft.com/en-us/dotnet/api/system.linq.expressions.expressionvisitor?view=netframework-4.7.1) like this:



```
using System.Linq.Expressions;

public static class ExpressionExtensions
{
    public static Expression ReplaceParameter(this Expression expression, ParameterExpression source, Expression target)
    {
        return new ParameterReplacer { Source = source, Target = target }.Visit(expression);
    }

    class ParameterReplacer : ExpressionVisitor
    {
        public ParameterExpression Source;
        public Expression Target;
        protected override Expression VisitParameter(ParameterExpression node)
        {
            return node == Source ? Target : base.VisitParameter(node);
        }
    }
}

```

Now regarding the EF Core combined query filters. 


Using dictionaries and expression lists seems overcomplicated for what are you doing. Since [`IMutableEntityType`](https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.metadata.imutableentitytype?view=efcore-2.1) provides read/write access to the [`QueryFilter`](https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.metadata.imutableentitytype.queryfilter?view=efcore-2.1#Microsoft_EntityFrameworkCore_Metadata_IMutableEntityType_QueryFilter), the same can be achieved with a small set of a custom extension methods.


All they go inside a class like this:



```
using System;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

public static class QueryFilterExtensions
{
}

```

First method:



```
public static void AddQueryFilter(this IMutableEntityType target, LambdaExpression filter)
{
    if (target.QueryFilter == null)
        target.QueryFilter = filter;
    else
    {
        var parameter = target.QueryFilter.Parameters[0];
        var left = target.QueryFilter.Body;
        var right = filter.Body.ReplaceParameter(filter.Parameters[0], parameter);
        var body = Expression.AndAlso(left, right);
        target.QueryFilter = Expression.Lambda(body, parameter);
    }
}

```

This is a non generic method which combines the exiting filter with passed filter using `AndAlso` (C# `&&`) operator and shows the aforementioned lambda expression combining principles.


However it's not so useful directly, like inside your entity type configuration loop (it can, but requires you to build manually the lambda expression instead of letting C# compiler do that). So here comes the second method:



```
public static void AddQueryFilter<T>(this IMutableEntityType target, Expression<Func<T, bool>> filter)
{
    LambdaExpression targetFilter = filter;
    if (target.ClrType != typeof(T))
    {
        var parameter = Expression.Parameter(target.ClrType, "e");
        var body = filter.Body.ReplaceParameter(filter.Parameters[0], parameter);
        targetFilter = Expression.Lambda(body, parameter);
    }
    target.AddQueryFilter(targetFilter);
}

```

It's a generic method - not quite type-safe, but allows you to use a compile time lambda expression and bind it to the actual entity type as follows:



```
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
    if (typeof(IDeleted).IsAssignableFrom(entityType.ClrType))
        entityType.AddQueryFilter<IDeleted>(e => e.DateTimeDeleted == null);
}

```

Looks better, isn't it :)


The last custom extension method is complement to (replacement of) the standard EF Core generic [`HasQueryFilter`](https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.metadata.builders.entitytypebuilder-1.hasqueryfilter?view=efcore-2.1#Microsoft_EntityFrameworkCore_Metadata_Builders_EntityTypeBuilder_1_HasQueryFilter_System_Linq_Expressions_Expression_System_Func__0_System_Boolean___) method:



```
public static EntityTypeBuilder<TEntity> AddQueryFilter<TEntity>(this EntityTypeBuilder<TEntity> target, Expression<Func<TEntity, bool>> filter)
    where TEntity : class
{
    target.Metadata.AddQueryFilter(filter);
    return target;
}

```

and allows you to replace



```
this.AddToDict<DbMyEntity>(t => t.Name == null || t.Name == "Something");

```

with the more convenient



```
modelBuilder.Entity<DbMyEntity>()
    .AddQueryFilter(t => t.Name == null || t.Name == "Something");

```

**Update (EF Core 3.0):** `QueryFilter` property has been replaced with `GetQueryFilter` and `SetQueryFilter` extension methods.