【发布时间】:2014-10-29 01:04:07
【问题描述】:
我有一个包含 4 个项目(XYZ.Domain、XYZ.Data、XYZ.Service 和 XYZ.Client)的解决方案 (XYZ)。我需要运行 WCF Web 服务。这是我的代码:
namespace XYZ.Domain
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
// Updated properties
[DataContract]
public class X : BaseClass
{
[DataMember]
[Key]
public int Xx { get; set; }
[DataMember]
[Required]
[StringLength(15)]
public string Xy { get; set; }
[DataMember]
public bool Xz { get; set; }
// Relationship with Y 1:1
[DataMember]
public virtual Y y { get; set; }
}
// Updated properties
[DataContract]
public class Y : BaseClass
{
[DataMember]
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Yx {get; set;}
[DataMember]
[Required]
[StringLength(15)]
public string Yy {get; set;}
[DataMember]
public DateTime Yz {get; set;}
// foreign key from Z
[DataMember]
public int Zx {get; set;}
// Relationship with X 1:1
[DataMember]
public virtual X x {get; set;}
// Relationship with Z *:1
[DataMember]
public virtual Z z { get; set; }
}
// Updated properties
[DataContract]
public class Z : BaseClass
{
public Z()
{
this.y = new HashSet<Y>();
}
[DataMember]
[Key]
public int Zx {get; set;}
[DataMember]
public DateTime Zy {get; set;}
[DataMember]
[Required]
public float Zz {get; set;}
// Relationship with Y 1:*
[DataMember]
public virtual ICollection<Y> y { get; set; }
}
// Added as a base class for my IServiceXYZ
[KnownType(typeof(X))]
[KnownType(typeof(Y))]
[KnownType(typeof(Z))]
[DataContract]
public class BaseClass
{
// empty
}
}
这是数据层:
namespace XYZ.Data
{
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.SqlServer;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XYZ.Domain;
public class Entities : DbContext
{
public Entities()
: base("name=Database")
{
Database.SetInitializer<Entities>(new CreateDatabaseIfNotExists<Entities>());
}
// Set of XYZ.Domain entity class
public DbSet<X> X { get; set; }
public DbSet<Y> Y { get; set; }
public DbSet<Z> Z { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<X>()
.HasOptional(e => e.y)
.WithRequired(e => e.x);
modelBuilder.Entity<X>()
.Property(e => e.Xy)
.IsUnicode(false);
modelBuilder.Entity<X>()
.Property(e => e.Xz);
modelBuilder.Entity<Y>()
.Property(e => e.Yy)
.IsUnicode(false);
modelBuilder.Entity<Y>()
.Property(e => e.Yz);
modelBuilder.Entity<Z>()
.HasMany(e => e.y)
.WithRequired(e => e.z)
.HasForeignKey(e => e.Zx)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Z>()
.Property(e => e.Zy);
modelBuilder.Entity<Z>()
.Property(e => e.Zz);
}
}
// Interface for Generic Repository where T : XYZ.Domain Entities
public interface IGenericRepository<T> where T : class, new()
{
void Insert(T entity);
void Update(T entity);
void Delete(T entity);
}
// Class generic for database persistence
public class GenericRepository<T> : IGenericRepository<T> where T : class, new()
{
public void Insert(T entity)
{
using (var _context = new Entities())
{
try
{
_context.Set<T>().Add(entity);
_context.SaveChanges();
}
catch(Exception ex)
{
throw;
}
}
}
public void Update(T entity)
{
using (var _context = new Entities())
{
try
{
_context.Entry(entity).State = EntityState.Modified;
_context.SaveChanges();
}
catch(Exception ex)
{
throw;
}
}
}
public void Delete(T entity)
{
using (var _context = new Entities())
{
try
{
_context.Set<T>().Remove(entity);
_context.SaveChanges();
}
catch(Exception ex)
{
throw;
}
}
}
}
}
这是服务层:
namespace XYZ.Service
{
using XYZ.Domain;
using XYZ.Data;
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IServiceXYZ" in both code and config file together.
[ServiceContract]
public interface IServiceXYZ
{
[OperationContract]
void Insert(BaseClass entity);
[OperationContract]
void Update(BaseClass entity);
[OperationContract]
void Delete(BaseClass entity);
}
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
public class ServiceXYZ : IServiceXYZ
{
private IGenericRepository<BaseClass> dao;
public ServiceXYZ()
{
dao = new GenericRepository<BaseClass>();
}
public void Insert(BaseClass entity)
{
dao.Insert(entity);
}
public void Update(BaseClass entity)
{
dao.Update(entity);
}
public void Delete(BaseClass entity)
{
dao.Delete(entity);
}
}
}
这是客户端测试:
namespace XYZ.Test
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// Service reference
using XYZ.Test.ServiceXYZ;
class Program
{
static void Main(string[] args)
{
try
{
ServiceXYZOf_BaseClassClient client = new ServiceXYZOf_BaseClassClient();
X x = new X
{
Xx = 1,
Xy = "ABCDEFGHIJKLMNÑ",
Xz = false
};
client.Insert(x);
client.Close();
}
catch (SystemException ex)
{
Console.Write(ex.Message);
}
Console.ReadLine();
}
}
}
但这是错误:
XYZ.Data.dll 中出现“System.InvalidOperationException”类型的异常,但未在用户代码中处理
附加信息:实体类型 BaseClass 不是当前上下文模型的一部分。
【问题讨论】:
-
我已经完成了尝试,相信我按照我在下面向您建议的方式实现它。对于 WCF Soap Services,泛型不是一个可行的选择。
-
最佳实践是不要一直共享您的实体,而仅将它们保留在数据层,而是创建它们的 POCO 表示并传递 POCO。从你正在做的紧密耦合中抽象出来。它将为您省去很多麻烦和问题。
标签: c# entity-framework wcf