1

I have a base class Dialog:

public class Dialog<T> : IDialogAble<T> where T : class, IEntity
{
    public IEntityService<T, int> Service { get; set; }

    public async Task Suchen(Expression<Func<T, bool>> criteria)
    {
        Cursor = Cursors.Wait;
        await Service.Search(criterian);
        Cursor = Cursors.Arrow;
    }
}

In this class I have a Service which is used in the base class and the derived class. I set the Service in the constructor:

Service = serviceFactory.CreateEntityService<MyObject, int>(context);

Now I have a object where my Service have to implement short not int because the primary key on the database is tinyint. So like this:

Service = serviceFactory.CreateEntityService<MyObject, short>(context);

But this doesn't work because short isn't convertible to int in this situation. The Problem is, that Dialog<T> cannot change to Dialog<T, TKey>. I tried with the new modifier, but this isn't work because I use the service in the base class:

public new IEntityService<OtherObject, short> Service { get; set; }

I don't find a solution for this, maybe someone has a idea.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
Presi
  • 806
  • 10
  • 26
  • You have to add functionality in the get/set to convert int to short. Something like this : private IEntityService _Service { get;set;} public IEntityService Service { get {return new IEntityService(T, (byte)(_Service.Value & 0xFF));} set { _Service = new IEntityService(Test, value.Value) ;} } – jdweng Sep 09 '19 at 12:31
  • I have to set the service in the derived class, so I cannot use such functionality. – Presi Sep 09 '19 at 12:44
  • You have a get/set in the derived class so there is no reason to add functionality in the get/set. – jdweng Sep 09 '19 at 12:50
  • I don't understand how you mean this. I don't want to set a value, I want to set the service. Or do I not understand your idea – Presi Sep 10 '19 at 05:58
  • The get/set on following line can contains code : public IEntityService Service { get; set; }. See answer 25 on following : https://stackoverflow.com/questions/5096926/what-is-the-get-set-syntax-in-c – jdweng Sep 10 '19 at 08:42

2 Answers2

1

Simple:

public class Dialog<T, TKey> : IDialogAble<T> where T : class, IEntity
{
    public IEntityService<T, TKey> Service { get; set; }

    public async Task Suchen(Expression<Func<T, bool>> criteria)
    {
        Cursor = Cursors.Wait;
        await Service.Search(criterian);
        Cursor = Cursors.Arrow;
    }
}

There is no other way to achieve it. BUT.

There is something very wrong in what you're doing. First of all keys in databse should all be of the same type. You shouldn't give key of type INT to one table and key of type short to other table. They should be all of the same type.

Don't be scared of using int as key, or even BIGINT (Int64, UInt64). They are great for this purpouse.

I bet that one of your tables is some kind of dictionary table that will only have several records - thus use of short as key. But don't do this.

Adam Jachocki
  • 1,897
  • 1
  • 12
  • 28
  • 1
    `You shouldn't give key of type INT to one table and key of type short to other table` why not? That's a perfectly sensible situation. – Jamiec Sep 09 '19 at 12:26
  • 4
    Keys in a database should not be of the same type necessarily. You're opinion is baseless. As an example, some entities might need a GUID/UUID, while others can simply be ordinal. – TvanB Sep 09 '19 at 12:27
  • Thank you. The problem is that the db is used a long time and changed from a lot people. The tables has many relations so I can't change the type of primary keys easily. – Presi Sep 09 '19 at 12:28
  • Upvoted, for the first part of your answer, which is the answer to the question. – Jesse de Wit Sep 09 '19 at 12:30
  • As far as I know, having primary keys of different types for different tables will have performance impact on joining or just on indexing operations. What's more, the best candidate for index is integer (also will be same performance impact, when this is not an int - but may be omitted in most cases), What's more, this may give some additional difficulty in working with that kind of code. – Adam Jachocki Sep 09 '19 at 12:38
  • The `TKey` worked. At first I had some issues with that, but it's the only possible solution for me. Thanks – Presi Sep 10 '19 at 06:18
1

If the generic parameter of the IEntityService is covariant, you could use IEntityService<T, object>.

Your class would then look like this:

public class Dialog<T> : IDialogAble<T> where T : class, IEntity
{
    public IEntityService<T, object> Service { get; set; }

    public async Task Suchen(Expression<Func<T, bool>> criteria)
    {
        Cursor = Cursors.Wait;
        await Service.Search(criterian);
        Cursor = Cursors.Arrow;
    }
}

And you could still set the Service like this:

    Service = serviceFactory.CreateEntityService<MyObject, int>(context);
TvanB
  • 112
  • 6