Save any new/changed entity respectively in Entity Framework - database

first, I was only trying to update a modified model. Lets say, we talk about "Article" as a model.
The following method is implemented in a class called "Articles":
public static void SaveArticle(Article article)
{
if (article.Id == 0)
{
webEntities.Articles.Add(article);
}
else
{
webEntities.Articles.Attach(article);
webEntities.Entry(article).State = EntityState.Modified;
}
webEntities.SaveChanges();
}
So whenever I want to save an modified article in a controller action, I just have to call "Articles.SaveArticle(myArticle);", which works as expected.
So far so good but this means I would need to implement this redundantly for every model/entity.
Then I thought about something like a template-pattern. I.e. a class called "Entity" where "Article" inherits from "Entity".
Furthermore, a class called "Entities" contains a static method like this:
public static void SaveEntity(Entity entity)
{
if (Entity.Id == 0) // <-- Problem 1
{
webEntities.Entities.Add(entity); // <-- Problem 2
}
else
{
webEntities.Entities.Attach(entity); // <-- Problem 3
webEntities.Entry(entity).State = EntityState.Modified; // <-- Problem 4
}
webEntities.SaveChanges();
}
So I would not need to implement it redundantly but I don't know how to solve the problems mentioned in the code above.
Do I think too complicated or what would be a best practice to my problem?
Thanks in advance!
Kind regards

Use generics.
public static void Save<T>(T entity)
where T : class
{
webEntities.Set<T>().AddOrUpdate(entity);
webEntities.SaveChanges();
}
AddOrUpdate is an extension method in System.Data.Entity.Migrations.

Related

How to skip invoking another method to create a mock object?

I have a class of methods, if I want to test one method, but the objects created in this method depend on other methods in the class. I don't want to actually call the other methods, I just want to create mock objects to test. How should I do it?
#Test
public void testLoadException(String id) {
WorkflowExecution mockWorkflowExection = getWorkflowExecution(id);
}
I tried to just do so
WorkflowExecution mockExecution = EasyMock.create(WorkflowExecution.class);
Easy.expect(this.test.getWorkflowExecution(EasyMock.anyString())).andReturn(mockExecution);
But this does not work, the test gives me Nullpointer exception.
So can I skip the calling of getWorkflowExecution(id), Thanks!
You need a partial mock. Your example doesn't make much sense. So here is what you seem to want.
public class WorkflowExecution {
public void theRealMethodIWantToCall() {
theMethodIWantToMock();
}
void theMethodIWantToMock() {
}
}
#Test
public void testLoadException() {
WorkflowExecution execution = partialMockBuilder(WorkflowExecution.class)
.addMockedMethod("theMethodIWantToMock")
.mock();
execution.theMethodIWantToMock();
replay(execution);
execution.theRealMethodIWantToCall();
verify(execution);
}

Is it possible to pass Java-Enum as argument from cucumber feature file

I am currently using selenium with Java,And want to implement cucumber to make test script more readable.
Currently facing issue while passing argument to java method where Enum is expected as parameter.
I would also like to know if there are any other known limitations of cucumber-java before migrating current framework.
The answer is: Yes
You can use all kind of different types in your scenario: primitive types, own classes (POJOs), enums, ...
Scenario :
Feature: Setup Enum and Print value
In order to manage my Enum
As a System Admin
I want to get the Enum
Scenario: Verify Enum Print
When I supply enum value "GET"
Step definition code :
import cucumber.api.java.en.When;
public class EnumTest {
#When("^I supply enum value \"([^\"]*)\"$")
public void i_supply_enum_value(TestEnum arg1) throws Throwable {
testMyEnum(arg1);
}
public enum TestEnum {
GET,
POST,
PATCH
}
protected void testMyEnum(TestEnum testEnumValue) {
switch (testEnumValue) {
case GET:
System.out.println("Enum Value GET");
break;
case POST:
System.out.println("Enum Value POST");
break;
default:
System.out.println("Enum Value PATCH");
break;
}
}
}
Let me know how you are doing. I could try to help you.
This youtube lecture of about 11 minutes gives a good way of doing it.
https://www.youtube.com/watch?v=_N_ca6lStrU
For example,
// enum, obviously in a separate file,
public enum MessageBarButtonType {
Speak, Clear, Delete, Share
}
// method for parameter type. if you want to use a different method name, you could do #ParameterType(name="newMethodName", value="Speak|Clear|Delete|Share") according to the video.
#ParameterType("Speak|Clear|Delete|Share")
public MessageBarButtonType MessageBarButtonType(String buttonType) {
return MessageBarButtonType.valueOf(buttonType);
}
// use like this. the name inside {} should match the name of method, though I just used the type name.
#Then("Select message bar {MessageBarButtonType} button")
public void select_message_bar_button(MessageBarButtonType buttonType) {
...
}
First register a transformer based on an ObjectMapper, then you can just use enums as would be expected.
private final ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
#DefaultParameterTransformer
#DefaultDataTableEntryTransformer
#DefaultDataTableCellTransformer
public Object defaultTransformer(Object fromValue, Type toValueType) {
JavaType javaType = objectMapper.constructType(toValueType);
return objectMapper.convertValue(fromValue, javaType);
}
Scenario: No.6 Parameter scenario enum
Given the professor level is ASSOCIATE
#Given("the professor level is {}")
public void theProfessorLevelIs(ProfLevels level) {
System.out.println(level);
System.out.println("");
}
public enum ProfLevels {
ASSISTANT, ASSOCIATE, PROFESSOR
}
Source
This is no more supported in latest io.cucumber maven group
https://github.com/cucumber/cucumber-jvm/issues/1393

How to share an Array between all Classes in an application?

I want to share an Array which all classes can "get" and "change" data inside that array. Something like a Global array or Multi Access array. How this is possible with ActionScript 3.0 ?
There are a couple of ways to solve this. One is to use a global variable (as suggested in unkiwii's answer) but that's not a very common approach in ActionScript. More common approaches are:
Class variable (static variable)
Create a class called DataModel or similar, and define an array variable on that class as static:
public class DataModel {
public static var myArray : Array = [];
}
You can then access this from any part in your application using DataModel.myArray. This is rarely a great solution because (like global variables) there is no way for one part of your application to know when the content of the array is modified by another part of the application. This means that even if your data entry GUI adds an object to the array, your data list GUI will not know to show the new data, unless you implement some other way of telling it to redraw.
Singleton wrapping array
Another way is to create a class called ArraySingleton, which wraps the actual array and provides access methods to it, and an instance of which can be accessed using the very common singleton pattern of keeping the single instance in a static variable.
public class ArraySingleton {
private var _array : Array;
private static var _instance : ArraySingleton;
public static function get INSTANCE() : ArraySingleton {
if (!_instance)
_instance = new ArraySingleton();
return _instance;
}
public function ArraySingleton() {
_array = [];
}
public function get length() : uint {
return _array.length;
}
public function push(object : *) : void {
_array.push(object);
}
public function itemAt(idx : uint) : * {
return _array[idx];
}
}
This class wraps an array, and a single instance can be accessed through ArraySingleton.INSTANCE. This means that you can do:
var arr : ArraySingleton = ArraySingleton.INSTANCE;
arr.push('a');
arr.push('b');
trace(arr.length); // traces '2'
trace(arr.itemAt(0)); // trace 'a'
The great benefit of this is that you can dispatch events when items are added or when the array is modified in any other way, so that all parts of your application can be notified of such changes. You will likely want to expand on the example above by implementing more array-like interfaces, like pop(), shift(), unshift() et c.
Dependency injection
A common pattern in large-scale application development is called dependency injection, and basically means that by marking your class in some way (AS3 meta-data is often used) you can signal that the framework should "inject" a reference into that class. That way, the class doesn't need to care about where the reference is coming from, but the framework will make sure that it's there.
A very popular DI framework for AS3 is Robotlegs.
NOTE: I discourage the use of Global Variables!
But here is your answer
You can go to your default package and create a file with the same name of your global variable and set the global variable public:
//File: GlobalArray.as
package {
public var GlobalArray:Array = [];
}
And that's it! You have a global variable. You can acces from your code (from anywhere) like this:
function DoSomething() {
GlobalArray.push(new Object());
GlobalArray.pop();
for each (var object:* in GlobalArray) {
//...
}
}
As this question was linked recently I would add something also. I was proposed to use singleton ages ago and resigned on using it as soon as I realized how namespaces and references work and that having everything based on global variables is bad idea.
Aternative
Note this is just a showcase and I do not advice you to use such approach all over the place.
As for alternative to singleton you could have:
public class Global {
public static const myArray:Alternative = new Alternative();
}
and use it almost like singleton:
var ga:Alternative = Global.myArray;
ga.e.addEventListener(GDataEvent.NEW_DATA, onNewData);
ga.e.addEventListener(GDataEvent.DATA_CHANGE, onDataChange);
ga.push(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "ten");
trace(ga[5]); // 5
And your Alternative.as would look similar to singleton one:
package adnss.projects.tchqs
{
import flash.utils.Proxy;
import flash.utils.flash_proxy;
public class Alternative extends Proxy
{
private var _data:Array = [];
private var _events:AltEventDisp = new AltEventDisp();
private var _dispatching:Boolean = false;
public var blockCircularChange:Boolean = true;
public function Alternative() {}
override flash_proxy function getProperty(id:*):* {var i:int = id;
return _data[i += (i < 0) ? _data.length : 0];
//return _data[id]; //version without anal item access - var i:int could be removed.
}
override flash_proxy function setProperty(id:*, value:*):void { var i:int = id;
if (_dispatching) { throw new Error("You cannot set data while DATA_CHANGE event is dipatching"); return; }
i += (i < 0) ? _data.length : 0;
if (i > 9 ) { throw new Error ("You can override only first 10 items without using push."); return;}
_data[i] = value;
if (blockCircularChange) _dispatching = true;
_events.dispatchEvent(new GDataEvent(GDataEvent.DATA_CHANGE, i));
_dispatching = false;
}
public function push(...rest) {
var c:uint = -_data.length + _data.push.apply(null, rest);
_events.dispatchEvent(new GDataEvent(GDataEvent.NEW_DATA, _data.length - c, c));
}
public function get length():uint { return _data.length; }
public function get e():AltEventDisp { return _events; }
public function toString():String { return String(_data); }
}
}
import flash.events.EventDispatcher;
/**
* Dispatched after data at existing index is replaced.
* #eventType adnss.projects.tchqs.GDataEvent
*/
[Event(name = "dataChange", type = "adnss.projects.tchqs.GDataEvent")]
/**
* Dispatched after new data is pushed intwo array.
* #eventType adnss.projects.tchqs.GDataEvent
*/
[Event(name = "newData", type = "adnss.projects.tchqs.GDataEvent")]
class AltEventDisp extends EventDispatcher { }
The only difference form Singleton is that you can actually have multiple instances of this class so you can reuse it like this:
public class Global {
public static const myArray:Alternative = new Alternative();
public static const myArray2:Alternative = new Alternative();
}
to have two separated global arrays or even us it as instance variable at the same time.
Note
Wrapping array like this an using methods like myArray.get(x) or myArray[x] is obviously slower than accessing raw array (see all additional steps we are taking at setProperty).
public static const staticArray:Array = [1,2,3];
On the other hand you don't have any control over this. And the content of the array can be changed form anywhere.
Caution about events
I would have to add that if you want to involve events in accessing data that way you should be careful. As with every sharp blade it's easy to get cut.
For example consider what happens when you do this this:
private function onDataChange(e:GDataEvent):void {
trace("dataChanged at:", e.id, "to", Global.myArray[e.id]);
Global.myArray[e.id]++;
trace("new onDataChange is called before function exits");
}
The function is called after data in array was changed and inside that function you changing the data again. Basically it's similar to doing something like this:
function f(x:Number) {
f(++x);
}
You can see what happens in such case if you toggle myArray.blockCircularChange. Sometimes you would intentionally want to have such recursion but it is likely that you will do it "by accident". Unfortunately flash will suddenly stop such events dispatching without even telling you why and this could be confusing.
Download full example here
Why using global variables is bad in most scenarios?
I guess there is many info about that all over the internet but to be complete I will add simple example.
Consider you have in your app some view where you display some text, or graphics, or most likely game content. Say you have chess game. Mayby you have separated logic and graphics in two classes but you want both to operate on the same pawns. So you create your Global.pawns variable and use that in both Grahpics and Logic class.
Everything is randy-dandy and works flawlessly. Now You come with the great idea - add option for user to play two matches at once or even more. All you have to do is to create another instance of your match... right?
Well you are doomed at this point because, every single instance of your class will use the same Global.pawns array. You not only have this variable global but also you have limited yourself to use only single instance of each class that use this variable :/
So before you use any global variables, just think twice if the thing you want to store in it is really global and universal across your entire app.

Silverlight 4 LoadOperation returns null

LoadOperation on the client side returns null? How can I fix it? Is my code correct? Is it a best practice?
Serverside (Domain service:
public IQueryable<State> GetStates()
{
return this.ObjectContext.States.Include("Country") ;
}
//-----------------------------------------------------------------------
Clientside
LoadOperation<State> loadOp;
public IEnumerable<State> Entities()
{
DSCommon _context = new DSCommon();
loadOp = _context.Load(_context.GetStatesQuery());
loadOp.Completed += complete;
loadOp.Completed += new EventHandler(LoadOp_Completed);
return loadOp.Entities;
}
EventHandler complete;
void LoadOp_Completed(object sender, EventArgs e)
{
foreach (var item in loadOp.Entities)
{
/************* item.Country is Null ********************/
}
}
Your question is not very clear as first you say that LoadOperation return null whereas in your code, you state that item.Country is null.
However, I believe that I see the problem.
In you Domain Service you call the Include("Country") method on the States EntityCollection. However, on client side, the State.Country Entity is still null? I had the same issue some time ago. It seems that RIA Services (or WCF) does not return those entities, unless you apply the [Include] attribute on the Entity you want to return like so in a metadata class
[MetadataType(typeof(State.StateMetadata))]
public partial class State
{
internal sealed class StateMetadata
{
private StateMetadata()
{
}
[Include]
public EntityCollection<Country> Country;
}
}
Someone will probably be able to give an explanation on why it works this way. I just know that I had to do it this way around :-)

Silverlight 4 - Type.GetType() not working across assemblies

Basically the problem is that I'd like to invoke a method in an unreferenced assembly, but can't seem to find the right call for instantiating the class. I've tried things like a simple Type t = Type.GetType("MyApp.Helper") which returns null, and Assembly.LoadFrom("MyApp.Helper") which throws a security exception.
In the example below, two projects/assemblies (Helper.dll and Menu.dll) are compiled separately into a common 'libs' folder, but do not reference each other. Main.dll references both, and the references are set to 'Copy local' in VS. So when the app runs, the Main.xap should contain all three assemblies and they should be loaded into the same application domain. Or so goes my understanding. Is this an impossible quest? I see lots of comments regarding plug-ins but so far I haven't seen examples for this specific design. For example, I suppose I could do something like Jeff Prosise describes here, but I'd rather have everything in one package.
Here's a sketch of my code:
In one project/assembly, I have a worker class:
namespace MyApp.Helper {
public class Helper {
public void ShowHelp() {
Console.Write("Help!");
}
}
}
In another project/assembly, I have a menu class which tries to invoke the helper:
namespace MyApp.Menu {
public class Selector {
public void InvokeSelection(string className, string functionName) {
// fails: t will be null
Type t = Type.GetType(className);
// fails: t will be null
t = Type.GetType(string.Format("{0}.{1}, {0}, Version=1.0.0.0, Culture=\"\", PublicTokenKey=null", "MyApp.Helper", "Helper"));
// however, this works (reference to main assembly?)
t = Type.GetType(string.Format("{0}.{1}, {0}, Version=1.0.0.0, Culture=\"\", PublicTokenKey=null", "MyApp.Main", "Worker"));
// and, I'd like to do something like the following
// t.InvokeMember(functionName, ...);
}
}
}
Finally, I have the main app assembly:
namespace MyApp.Main {
public class Main {
public static void Main() {
MyApp.Menu.Selector sel = new Menu.Selector();
sel.InvokeSelection("MyApp.Help.Helper", "ShowHelp"); // fails
sel.InvokeSelection("MyApp.Main.Main", "Worker"); // works in some cases
}
public void Worker() {
Console.Write("Work!");
}
}
}
Thanks for any ideas!
-Chris.
You need to get the Assembly object, then call its GetType method.
However, I don't see why you're using Reflection at all.
You can call the method normally from your main project.
First, you should note that since it's SL, you can't invoke private/protected/internal members.
Second, try this:
public void InvokeSelection(string className, string functionName) {
var asm = Assembly.Load("MyApp.Helper, Version=1.0.0.0, Culture=\"\", PublicTokenKey=null"); // double check this is correct!
Type t = asm .GetType(className);
// and, I'd like to do something like the following
// t.InvokeMember(functionName, ...);
}

Resources