Entity Framework mapping to table - entity-framework-6

I am trying to define a mapping to another table using the following method:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Ansprechpartner>().Map(x => x.ToTable("Ansprechpartnerdaten"));
I created two DbContexts: One default context containing entities which should not be modified (private setter)
and another EditContext which should be used when editing.
I get the following error Message (sorry - in German):
EditContextTest.TestMethod1-Testmethode hat eine Ausnahme ausgelöst:
System.InvalidOperationException: Die Entitätstypen 'Ansprechpartner'
und 'AnsprechpartnerEdit' können die Tabelle 'Ansprechpartner' nicht
gemeinsam verwenden, weil sie sich nicht in derselben Typhierarchie
befinden und nicht über eine gültige 1:1-Fremdschlüsselbeziehung mit
übereinstimmenden Primärschlüsseln verfügen.
Error message says that Entity Framework is trying to map Ansprechpartner and AnsprechpartnerEdit to table Ansprechpartner.
So I am trying to map:
Model | Table
--------------------+---------------------
Ansprechpartner | Ansprechpartnerdaten
AnsprechpartnerEdit | Ansprechpartner
which doesn't work for some reason.

So one option is to rename the Model class Ansprechpartner to another name.
I tested AnsprechpartnerXX. I don't want to rename the class, I cannot come up with a better / different name. You know naming things is one of the hard problems in CS.
Another solution is to Ignore all Ansprechpartner related things in the mapping:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Ignore<Ansprechpartner>();
modelBuilder.Ignore<AktivitätenAnsprechpartner>();
modelBuilder.Ignore<AnsprechpartnerInteressen>();
modelBuilder.Ignore<VerkaufschancenAnsprechpartner>();
modelBuilder.Ignore<LeadsAnsprechpartner>();
I am doing that for now. I don't need this classes for now and I plan to implement a EditModel for them aswell anyway.
I still hope there are other solutions.

Related

Invalid column name 'UserId' and 'IdentityUser_Id' when trying to log-in/register

I have been trying to build my own online shop in MVC based on the OpenOrderFramework located here - https://github.com/lbacaj/OpenOrderFramework
I've managed to get everything working perfectly apart from when it comes to trying to log in, register, or complete checkout - basically anything to do with Identity.
The error I keep getting is either:
Invalid column name 'UserId'.
or
Invalid column name 'IdentityUser_UserId'.
As part of the process, I have created my own custom AspNet Identity tables (AspNetRoles, AspNetUserClaims, AspNetUserLogins, AspNetUserRoles, AspNetUsers)
When I say custom, they all follow the standardised default format apart from the AspNetUsers table which has some additional new fields in there. They are nevertheless fed into the project like so:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder); // This needs to go before the other rules!
modelBuilder.Entity<ApplicationUser>().ToTable("TSSC_AspNetUsers", "dbo");
modelBuilder.Entity<IdentityUser>().ToTable("TSSC_AspNetUsers", "dbo");
modelBuilder.Entity<IdentityUserRole>().ToTable("TSSC_AspNetUserRoles", "dbo");
modelBuilder.Entity<IdentityRole>().ToTable("TSSC_AspNetRoles", "dbo");
modelBuilder.Entity<IdentityUserLogin>().ToTable("TSSC_AspNetUserLogins", "dbo");
modelBuilder.Entity<IdentityUserClaim>().ToTable("TSSC_AspNetUserClaims", "dbo");
}
Depending on what I try, the invalid column name error can appear up to three times for the same field which I find odd.
I took a look at the SQL query string being generated inside the UserManager and this is what it returned:
+
((Microsoft.AspNet.Identity.UserManager<TSSC.Models.ApplicationUser,string>)(UserManager)).Users {SELECT
'0X0X' AS [C1],
[Extent1].[IdentityUser_Id] AS [IdentityUser_Id],
[Extent1].[Email] AS [Email],
[Extent1].[EmailConfirmed] AS [EmailConfirmed],
[Extent1].[PasswordHash] AS [PasswordHash],
[Extent1].[SecurityStamp] AS [SecurityStamp],
[Extent1].[PhoneNumber] AS [PhoneNumber],
[Extent1].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed],
[Extent1].[TwoFactorEnabled] AS [TwoFactorEnabled],
[Extent1].[LockoutEndDateUtc] AS [LockoutEndDateUtc],
[Extent1].[LockoutEnabled] AS [LockoutEnabled],
[Extent1].[AccessFailedCount] AS [AccessFailedCount],
[Extent1].[UserName] AS [UserName]
FROM [dbo].[TSSC_AspNetUsers] AS [Extent1]
WHERE [Extent1].[Discriminator] = N'ApplicationUser'}
System.Linq.IQueryable<TSSC.Models.ApplicationUser>
{System.Data.Entity.DbSet<TSSC.Models.ApplicationUser>}
As you can see, it is looking for a column called 'IdentityUser_UserId' which doesn't exist. The field is actually 'Id'.
Any help or advice would be appreciated. This is driving me nuts.

How to correctly address "can't add a _parent field that points to an already existing type, that isn't already a parent" on app startup

I'm running into a problem with my Elasticsearch Document index creation failing on startup with "java.lang.IllegalArgumentException: can't add a _parent field that points to an already existing type, that isn't already a parent". I'm not sure if this is due to a version upgrade or b/c I am starting with a brand new Elasticsearch server install.
Contrived example that shows what I'm seeing:
// UserSearchResult.java
#Document(indexName = "hr_index", type = "user")
public class UserSearchResult implements Serializable {
...
#Field(type=FieldType.keyword)
#Parent(type="department")
private String departmentCode;
...
}
// DepartmentSearchResult.java
#Document(indexName = "hr_index", type = "department")
public class DepartmentSearchResult implements Serializable {
...
}
When I start my application I get that exception. If I check the ElasticSearch server, I see the "hr_index" index and the "department" mapping, but the "user" mapping is not created.
If I understand the error, it's because "department" is being created and then when Spring tries to create "user" with "department" as its parent, it doesn't like that, since department wasn't previously marked as a parent when it was created.
Is there some way (via annotation?) to denote DepartmentSearchResult as being a parent when it's created somehow?
Or, is it possible to give a hint to Spring Data Elasticsearch as to what order it should create the indices/mappings? I have seen some other posts (Spring Data Elasticsearch Parent/Child Document Repositories / Test execution error) but disabling auto creation and then manually creating it myself (either as part of my Spring codebase or external to the app) seems kind of "un-Spring-y" to me?
Or, is there some other approach I should be taking?
(This is a working Spring application that had been using Spring 4.2.1 and Spring Data Release Train Gosling, that I'm attempting to upgrade to use Spring 5.0.0 and Spring Data Release Train Kay. As part of this I am starting with a fresh Elasticsearch install, and so I'm not sure if this error is coming from the upgrade or just b/c the install is clean).
In the SD ES, issues related to the parent-child relationship at now really poorly developed.
The problem is most likely due to the fact that you are using a clean installation of Elasticsearch. Before the update, the problem did not arise, because mappings have already been created. For the solution, you can use elasticsearchTemplate, which is part of SD ES, and ApplicationListener. It's simple. Just 3 steps.
Drop index in ES (it only needs one time):
curl -XDELETE [ES_IP]:9200/hr_index
Tell SD ES not to create indices and mappings automatically
// UserSearchResult.java
#Document(indexName = "hr_index", type = "user", createIndex = false)
public class UserSearchResult implements Serializable {
...
#Field(type=FieldType.keyword)
#Parent(type="department")
private String departmentCode;
...
}
// DepartmentSearchResult.java
#Document(indexName = "hr_index", type = "department", createIndex = false)
public class DepartmentSearchResult implements Serializable {
...
}
Add a ApplicationListener:
#Component
public class ApplicationStartupListener implements ApplicationListener<ContextRefreshedEvent> {
#Autowired
private ElasticsearchTemplate elasticsearchTemplate;
//Mapping for child must be created only if mapping for parents doesn't exist
#Override
public void onApplicationEvent(ContextRefreshedEvent event) {
elasticsearchTemplate.createIndex(DepartmentSearchResult.class);
try {
elasticsearchTemplate.getMapping(DepartmentSearchResult.class);
} catch (ElasticsearchException e) {
elasticsearchTemplate.putMapping(UserSearchResult.class);
elasticsearchTemplate.putMapping(DepartmentSearchResult.class);
}
}
}
P.S. Among other things, it is worth paying attention to the fact that with the release of ES 5.6, a process for removing types began. This inevitably entails the removal of the parent-child relationship. In one of the next releases of the SD ES, we will provide the opportunity to work with joins. Working with parent-child relationships is unlikely to be improved

Use ZF2 controller plugins for application services within an DDD?

I am currently using DDD (Domain Driven Design) for a new Zend Framework 2 project. Everything works fine but I do have a question regarding the application services.
I understood that application services are located at the application layer and are kind of the entry point to the domain logic. They can access domain services or the repository for example.
I wonder now if it would make sense to implement the application services as controller plugins. In a classical MVC application this controller plugin could handle the results from the called domain services or repositories. Depending on these results they could generate a redirect response or pass data / a form to a ViewModel. If this logic is encapsulated within a plugin my controller only has to call the plugin and return the result of the plugin.
Am I totally wrong about this? Or would you rather keep the logic how to react on results of a domain service or a repository in a controller?
Best Regards,
Ralf
Of course it's kind of subjective and people have strong opinions about things like that... so here's mine:
Controller plugins contain code that's universal to any MVC/REST
action and business logic is not universal. Plugins are supposed to facilitate the
"controlling" of request/response and not the business logic that's
down on the model level. Linking it there would make it less
reusable, e.g. for console actions. Also it'd make it less probable
to use the business logic with some other framework.
It's awkward to test. Injecting controller plugins as controller
class constructor parameters would be kinda redundant, since they are already
available from the plugin manager injected into AbstractActionController or AbstractRestfulController. Not having the dependencies injected in a obivious/visible way (like trough contructor method) makes it harder to figure out what the controller class actually depends
on. Also since all plugins (AbstractPlugin related) depend on controller instance, switching context from
http to console (like for a phpunit test) might get problematic. Also testing logic
written/made available as controller plugin would sooner or later
escalate to including request/response objects in the tests and
that's unnecessary complexity.
It's not intuitive. When I hear plugin I think of something small.
Not a full-blown business logic code buried under such inconspicuous
name. So when I have little time to debug someones code the last
thing I need it to things be out of place like that.
Again I'd like to reiterate, that's just my opinion. I've learned that a lot of patterns can crumble under a weird-enough use case, but the above points made sense to me and my team so far.
As an example for my solution here you can see an controller action:
public function showAction()
{
$service = $this->readProductEntityCommand;
$service->setId($this->params()->fromRoute('id'));
try {
$result = $service->execute();
} catch (ProductException $e) {
$this->flashMessenger()->addMessage($e->getMessage());
return $this->redirect()->toRoute('part3/product');
}
return new ViewModel(
array(
'productEntity' => $result->getData(),
)
);
}
And here is an example of an application service build as an command object
class ReadProductEntityCommand implements CommandInterface
{
protected $productRepository;
protected $id;
public function __construct(ProductRepositoryInterface $productRepository)
{
$this->productRepository = $productRepository;
}
public function setId($id)
{
$this->id = $id;
}
public function execute()
{
if (is_null($this->id)) {
throw new ProductIdInvalidException(
'Produkt ID wurde nicht angegeben.'
);
}
try {
$product = $this->productRepository->getProduct(
new ProductIdCriterion(
new ProductId($this->id)
)
);
} catch (\Exception $e) {
throw new ProductNotFoundException(
'Es konnten kein Produkt gelesen werden.'
);
}
if ($product === false) {
throw new ProductNotFoundException('Produkt wurde nicht gefunden.');
}
$result = new Result();
$result->setValid(true);
$result->setData($product);
$result->setMessage('Produkt wurde gelesen.');
return $result;
}
}
Maybe this helps someone in the future.

Making DropCreateDatabaseAlways work with custom DbMigrationsConfiguration

Using ef6 code first and mysql I got the following exception:
Specified key was too long; max key length is 767 bytes.
To fix it I created custom HistoryContext and shortened ContextKey length.
And to use MyHistoryContext I created Configuration class inherited from DbMigrationsConfiguration<MyContext>.
After creation of Configuration class DropCreateDatabaseAlways db initializer stopped to work throwing:
The DropCreateDatabaseAlways initializer did not drop or create the database backing context 'MyContext' because Migrations are enabled for the context.
A̶n̶d̶ ̶s̶e̶t̶t̶i̶n̶g̶ ̶A̶u̶t̶o̶m̶a̶t̶i̶c̶M̶i̶g̶r̶a̶t̶i̶o̶n̶s̶E̶n̶a̶b̶l̶e̶d̶ ̶t̶o̶ ̶f̶a̶l̶s̶e̶ ̶d̶i̶d̶n̶t̶ ̶h̶e̶l̶p̶. (I've understood that its unrelated.)
Edit.
I want to reformulate the problem: creating Configuration class inherited from DbMigrationsConfiguration<MyDbContext> (to use custom HistoryContext wich solves Specified key was too long problem in mysql) made ef think that I've enabled migrations via Enable-Migrations command and DropCreateDatabaseAlways stopped to work (but this is intended behaviour as far as I understand). But afterall this is not a big problem because I can create custom initializer with
context.Database.Create();
context.Database.Drop();
So, did I understand it correct?
Custom HistoryContext:
public class MyDbHistoryContext : HistoryContext
{
public MyDbHistoryContext(DbConnection existingConnection, string defaultSchema)
: base(existingConnection, defaultSchema)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<HistoryRow>()
.Property(x => x.ContextKey)
.HasMaxLength(255);
}
}

InvalidOperationsException during XML-Serialization in XNA

I have a question concerning an Error I experience while trying to read an XML-File through the XNA 4.0 Content Pipeline in order to build Objects. First I reused old XNA 3.1 Code of mine which worked back in the day but now throws the an Error Message:
Building content threw InvalidOperationException: Instanzen von abstrakten Klassen können nicht erstellt werden. (Unable to build Instances of abstract Classes - roughly translated)
at ReflectionEmitUtils()
...and goes on forever, I can post it, if it's needed, but for better readability of my initial request..
Then I used this Method but it throws the same error.
These are the relevant pieces of source code:
I've written a class to define the content/structure of the XML-File:
public class Command
{
public List<bool> mButtons;
public List<Keys> keys;
public Enum iD;
}
And this is my XML File, with which I want to build Command-Objects
<?xml version="1.0" encoding="utf-8" ?>
<XnaContent>
<Asset Type="KinectRTS_Input.Command">
<mButtons>true/mButtons>
<keys>
<Item>LeftControl/Item>
</keys>
<iD>SMulti/iD>
</Asset>
</XnaContent>
(In my code, the Brackets are all correct, though since this Form processes XML-Tags...;))
I used a Test-Application in order to find out, which Format the XNA-Serializer uses to output List-Items and enums, so I'm reasonably sure, that there's not the error.
It looks like either your XML is invalid or your Model is. For the mButtons field, you have defined it as a List<bool> but in the XML it's a bool not a List<bool>. I would either edit the XML to have the <mButtons> element contain a single <Item> element or change the declaration of mButtons in the Model to be a bool not List<bool>.
Too easy...the problem wasn't with the Lists, in fact the Test-Application mentioned in my request actually returned XML-Tags with Item-Tags for the keys-List and without Item-Tags for the bool-list. Wrapping the bool into Item-Tags resulted in an " at not expected"-Error. I have no idea, why the Serializer handles List and List differently, though.
The problem was the Enum 'iD', which is an abstract class and thus throws the Error mentiones above. It seems that I was overwhelmed by the sheer size of the error-message and just disregarded the crucial bit of info - that the Serializer tries to build an abstract class.
But thanks anyway. – Kuroni Kaimei

Resources