WCF 数据服务 + 带有枚举的实体

Posted

技术标签:

【中文标题】WCF 数据服务 + 带有枚举的实体【英文标题】:WCF Data Services + Entities with Enums 【发布时间】:2019-12-18 19:31:55 【问题描述】:

我正在学习 WCF 数据服务(5.6.4 版)。我找到了一个非常基本的例子。

CodeFirstSampleService.svc.cs 的代码:

public class CodeFirstSampleService : EntityFrameworkDataService<BlogContext>

    public static void InitializeService(DataServiceConfiguration config)
    
        config.SetEntitySetAccessRule("*", EntitySetRights.All);
        config.SetServiceOperationAccessRule("*", ServiceOperationRights.AllRead);
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
        AddDataToBlogContext(new BlogContext());
    

    private static void AddDataToBlogContext(BlogContext dataSource)
    
        var b1 = new Blog()  BlogId = 1, BlogName = "SampleBlog" ;
        dataSource.Blogs.Add(b1);
        dataSource.Posts.Add(new Post()
        
            Blog = b1,
            BlogId = b1.BlogId,
            PostId = 1,
            PostName = "Using EntityFrameworkProvider"
        );
        dataSource.SaveChanges();
    

    [WebGet]
    public string GetFirstPostName()
    
        var context = new BlogContext();
        return context.Posts.Select(x => x.PostName).FirstOrDefault();
    

DataModel.cs 的代码

public class Blog

    public int BlogId  get; set; 
    public string BlogName  get; set; 
    public virtual List<Post> Posts  get; set; 


public class Post

    public int PostId  get; set; 
    public string PostName  get; set; 
    //public ColorEnum Color  get; set; 
    //public PostContent Content  get; set; 
    public int BlogId  get; set; 
    public virtual Blog Blog  get; set; 


public class BlogContext : DbContext

    public DbSet<Blog> Blogs  get; set; 
    public DbSet<Post> Posts  get; set; 

效果很好。如果我开始调试(在浏览器中):

现在假设我在 Post 实体中也有一个枚举。

public class Post

    public int PostId  get; set; 
    public string PostName  get; set; 
    public ColorEnum Color  get; set;  // <---- added ENUM here
    public int BlogId  get; set; 
    public virtual Blog Blog  get; set; 


public enum ColorEnum

    Red,
    Green,
    Blue

在运行时,启动服务时出现错误:“Post”类型上的“Color”属性属于“ColorEnum”类型,它不是受支持的原始类型。

我知道:WCF 数据服务不支持枚举。

一些解决方法是可能的:

例如在枚举属性上使用[NotMapped] 属性。但在我的情况下,我不能那样做,因为我已经在生产中使用 EF Code First 的解决方案,因为几年来有一些枚举并且我需要它,我不能简单地用实体上的 [NotMapped] 属性忽略它。

我尝试添加 [DataMember][DataContract] 属性但它不起作用:仍然收到有关枚举的错误消息。

[DataContract]
public class Post

   [DataMember]
   public int PostId  get; set; 
   [DataMember]
   public string PostName  get; set; 

   public ColorEnum Color  get; set; 
   [DataMember]
   public int BlogId  get; set; 
   public virtual Blog Blog  get; set; 

还有哪些其他选择?

请注意,我在我的上下文中有(假设是)20 个实体,但只需要其中 2 个就可以在我的 WCF 数据服务中使用。此外,只需要这 2 个实体处于“只读”模式(无需创建、更新等)。

如何使我的实体与枚举保持可用于应用程序的其余部分,但防止枚举属性在我的 WCF 数据服务中出现错误?

还请注意,我已经搜索了有关此主题的其他 SO 问题,但没有找到任何解决方案允许我在现有实体上保留枚举。

【问题讨论】:

【参考方案1】:

您是否尝试过 MSDN 示例表单 https://social.msdn.microsoft.com/Forums/en-US/e844d7e1-cdf3-4631-82e0-e1a096e91d7e/wcf-enum-datacontract-serialization?forum=wcf

你用 [DataContract] 属性装饰你的枚举类,然后将你的枚举设置为

[枚举成员]

[DataContract]
public class Car

    [DataMember]
    public string model;
    [DataMember]
    public CarConditionEnum condition;


[DataContract(Name = "CarCondition")]
public enum CarConditionEnum

    [EnumMember]
    New,
    [EnumMember]
    Used,
    [EnumMember]
    Rental,
    Broken,
    Stolen

【讨论】:

是的,我已经尝试用[EnumMember] 装饰我的枚举的每个值,但它不起作用。似乎所有这些属性[DataContract] ... [DataMember] ... [EnumMember] 都不适用于 WCF 数据服务。希望有人可以确认或解释这里的诀窍。

以上是关于WCF 数据服务 + 带有枚举的实体的主要内容,如果未能解决你的问题,请参考以下文章

如何在数据合同 WCF 中使用枚举

您是不是在 WCF Web 服务中使用枚举类型?

带有 EF 和自动映射器的 OData:无法比较..'。仅支持原始类型、枚举类型和实体类型

将标志添加到枚举后:Wcf 错误:错误 5 自定义工具错误:无法为服务引用“MyService”生成代码

将单个枚举值传递给 WCF 服务时,protobuf-net 引发有关无效线路类型的异常

WCF 确保存在必要的枚举值