c# - System.InvalidOperationException in WCF and EF -
c# - System.InvalidOperationException in WCF and EF -
i have solution (xyz) 4 projects (xyz.domain, xyz.data, xyz.service , xyz.client). need run wcf web service. code:
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 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 z [datamember] public int zx {get; set;} // relationship x 1:1 [datamember] public virtual x x {get; set;} // relationship 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 y 1:* [datamember] public virtual icollection<y> y { get; set; } } // added base of operations class iservicexyz [knowntype(typeof(x))] [knowntype(typeof(y))] [knowntype(typeof(z))] [datacontract] public class baseclass { // empty } }
this info layer:
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 generic repository t : xyz.domain entities public interface igenericrepository<t> t : class, new() { void insert(t entity); void update(t entity); void delete(t entity); } // class generic database persistence public class genericrepository<t> : igenericrepository<t> t : class, new() { public void insert(t entity) { using (var _context = new entities()) { seek { _context.set<t>().add(entity); _context.savechanges(); } catch(exception ex) { throw; } } } public void update(t entity) { using (var _context = new entities()) { seek { _context.entry(entity).state = entitystate.modified; _context.savechanges(); } catch(exception ex) { throw; } } } public void delete(t entity) { using (var _context = new entities()) { seek { _context.set<t>().remove(entity); _context.savechanges(); } catch(exception ex) { throw; } } } } }
this service layer:
namespace xyz.service { using xyz.domain; using xyz.data; // note: can utilize "rename" command on "refactor" menu alter interface name "iservicexyz" in both code , config file together. [servicecontract] public interface iservicexyz { [operationcontract] void insert(baseclass entity); [operationcontract] void update(baseclass entity); [operationcontract] void delete(baseclass entity); } // note: can utilize "rename" command on "refactor" menu alter class name "service1" in code, svc , config file together. // note: in order launch wcf test client testing service, please select service1.svc or service1.svc.cs @ solution explorer , 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); } } }
and client test:
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 programme { static void main(string[] args) { seek { servicexyzof_baseclassclient client = new servicexyzof_baseclassclient(); x x = new x { xx = 1, xy = "abcdefghijklmnÑ", xz = false }; client.insert(x); client.close(); } grab (systemexception ex) { console.write(ex.message); } console.readline(); } } }
but error:
an exception of type 'system.invalidoperationexception' occurred in xyz.data.dll not handled in user code
additional information: entity type baseclass not part of model current context.
using service contract based on generics not idea, you'd have update web.config possible datatypes service contract.
if insist on type of configuration need have wcf service utilize serializer embed clr info type info in payload. netdatacontractserializer that, should have mutual assembly(s) both client , server share hold these info types.
if trying "pure" wcf doing not going jive gotcha's you'll have contend with.
you can create service sends object subclass of base of operations class, illustration if class x, y , z extended base of operations class ( let's phone call baseclass
) service contract based off of that.
so you'd end service this:
public class servicexyz : iservicexyz { // xyz.data persistence object public void insert(baseclass entity) { //get ef context var context = new entities(); // <-- method ef context context.entry(entity).state = added; //<- attach , add together }
now need add together knowntypes
of baseclass
, wcf needs know possible .net types baseclass
[knowntype(typeof(x)] [knowntype(typeof(y)] [knowntype(typeof(z)] [datacontract] public class baseclass { ... }
and you'd need alter info contract extend baseclass
[datacontract] public class x : baseclass { ...} [datacontract] public class y : baseclass { ...} [datacontract] public class z : baseclass { ...}
update
[servicecontract] public interface iservicexyz // no generics!! base of operations class { [operationcontract] void insert(baseclass entity); [operationcontract] void update(baseclass entity); [operationcontract] void delete(baseclass entity); }
as have explained above can attach entity using context , setting entities state. @ implementation of service class did...
c# entity-framework wcf
Comments
Post a Comment